<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="https://www.w3.org/2005/Atom">
  <title>MLee</title>
  
  <subtitle>MLee 思考的地方</subtitle>
  <link href="/atom.xml" rel="self"/>
  
  <link href="https://makingl.github.io/"/>
  <updated>2019-11-25T03:58:16.065Z</updated>
  <id>https://makingl.github.io/</id>
  
  <author>
    <name>MLee</name>
    
  </author>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  
  <entry>
    <title>暗时间 读书笔记——第一篇</title>
    <link href="https://makingl.github.io/2019/11/25/%E6%9A%97%E6%97%B6%E9%97%B4-%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0%E2%80%94%E2%80%94%E7%AC%AC%E4%B8%80%E7%AF%87/"/>
    <id>https://makingl.github.io/2019/11/25/%E6%9A%97%E6%97%B6%E9%97%B4-%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0%E2%80%94%E2%80%94%E7%AC%AC%E4%B8%80%E7%AF%87/</id>
    <published>2019-11-25T03:47:39.000Z</published>
    <updated>2019-11-25T03:58:16.065Z</updated>
    
    <content type="html"><![CDATA[<h2 id="为何选择看这本书"><a href="#为何选择看这本书" class="headerlink" title="为何选择看这本书"></a>为何选择看这本书</h2><p>之前多次在不同地方看到有推荐看这本书，最近恰好手边没什么人文类书籍可看，在图书馆借书的时候，翻了一下此书目录，包括有关心理学、时间管理的主题，而且作者的表达简练，许多观点也比较契合本人观念，是一本适合利用琐碎时间看的书，故开始看此书。</p><p>看书的时候发现，其实书中的内容作者其实也在其个人博客网站上发的有： <a href="http://mindhacks.cn/" target="_blank" rel="noopener">刘未鹏 | Mind Hacks</a>。</p><h2 id="关于这个读书笔记"><a href="#关于这个读书笔记" class="headerlink" title="关于这个读书笔记"></a>关于这个读书笔记</h2><p>看此书的过程中发现许多观点其实自己也有过，只是过去没有总结、记笔记的习惯，语言表达也没有这么好。本人经常有这样的场景，脑袋里有一些想法，想记录下来的时候，发现脑袋里的一堆东西，只记下了短短几句话。嗯，总结能力欠缺！这其实也是我想要写博客的原因。看到作者也提倡记笔记，故索性写成读书笔记的形式，记录一些个人觉得精彩的语录，以及看书时所联想到的个人经历。</p><a id="more"></a><h2 id="精彩语录"><a href="#精彩语录" class="headerlink" title="精彩语录"></a>精彩语录</h2><h3 id="暗时间"><a href="#暗时间" class="headerlink" title="暗时间"></a>暗时间</h3><ol><li><blockquote><p>善于利用思维时间的人，可以无形中比别人多出很多时间，从而实际意义上能比别人多活很多年。<strong>我们经常听说“心理年龄”这个词，思考得多的人，往往心理年龄更大</strong>。</p></blockquote></li><li><blockquote><p>每个人的手表都走得一样快，但每个人的生命却不是。衡量一个人生活了多少年，应该用思维时间来计算。</p></blockquote></li><li><blockquote><p>如果你有做总结的习惯，你在度过一段时间之后总结自己在某某领域投入了多少时间，建议千万不要粗略地去计算有多少天下班后拿起书来翻看过，因为这样你也许会发现书倒是常翻，但领悟却不见得多深，表面上花的时间不少，收益却不见得那么大。因为看书并记住书中的东西只是记忆，并没有涉及推理，<strong>只有靠推理才能深入理解一个事物</strong>，看到别人看不到的地方，这部分推理的过程就是你的思维时间，也是人一生中占据一个显著比例的“暗时间”，你走路、买菜、洗脸洗手、坐公车、逛街、出游、吃饭、睡觉，所有这些时间都可以成为“暗时间”，你可以充分利用这些时间进行思考，<strong>反刍和消化平时看和读的东西，让你的认识能够脱离照本宣科的层面</strong>。这段时间看起来微不足道，但日积月累将会产生庞大的效应。</p></blockquote><p> ( <strong>此部分是本人观点， 下同</strong> ) 看到有人的观点是，如果只是一味的记录别人的观点及知识点，没有自己的思考及观点，那么博客文章应该全是别人的，而不是自己的。的确，知识需要自己深入理解并总结后，用自己的话，简要的表述出来，才能够勉强算得上理解知识。</p><p> 记得大学刚入学时，一位老师也是跟我说过，大学的许多专业知识是需要课后花大量时间去深入思考、理解的，有许多知识也许需要动手实践后才能完全理解的。大学期间深有体会，有时候想仅仅通过上课听老师讲就搞懂知识点，发现很有难度（<em>本人学的工科，且理解能力一般</em>），许多算法都是自己下来看了几遍，动手推导后才理解的。平时学习编程知识也深有体会，许多书上介绍的词法、语法，看书的时候往往不太理解，许多知识点本人通常是敲代码实践时才理解一些语法的作用（《如何阅读一本书》里介绍的阅读技术类书籍的技巧里有这一点）。</p></li><li><blockquote><p>程序员们都知道，任务切换需要耗费许多额外的花销，通俗地来讲，首先需要保存当前上下文以便下次能够顺利切换回来，然后要加载目标任务的上下文。如果一个系统不停地在多个任务之间来回倒腾，就会耗费大量的时间在上下文切换上，无形中浪费很多的时间。相比之下，如果只做一件任务，就不会有此损失。<strong>这就是为什么专注的人比不专注的人时间利用效率高得多的原因</strong>。</p></blockquote></li><li><blockquote><p>能够迅速进入专注状态，以及能够长期保持专注状态，是高效学习的两个最重要习惯。</p></blockquote></li></ol><h3 id="学会设计自己的进度条"><a href="#学会设计自己的进度条" class="headerlink" title="学会设计自己的进度条"></a>学会设计自己的进度条</h3><ol><li><blockquote><p>进度条的设计是一个很多人都知道的故事：<strong>同样的耗时，如果不给任何进度提示，只是在完成之后才弹出一个完成消息，中间没有任何动态变化，那么整个过程就会让人等得非常焦急，导致一些人干脆把程序关了了事</strong>。如果有进度不断更新，那么对整个过程耗时的心理感受就会远低于实际值，用户也不会郁闷到把程序关了。（你有多少次在银行处理手续的时候，看着工作人员把一堆材料不停地倒腾来去，心里多希望他们可以在柜台小窗口上投影一个进度条？）</p></blockquote><p> 给自己的任务、规划设置进度条，设置 TODO List，在给自己定制了长期目标以后通常还会定制短期目标，也许正是此原因，有了短期坚持及付出后能够达到的目标，目标的达成能够正向的激励我们持续的做下去，而且对于比较急的任务，当 TODO List 上的任务被一个一个的完成的时候，心里的焦虑通常会少很多。</p></li><li><blockquote><p>所谓的规划其实就是针对这种心理弱点的做事方法。如果你对整个目标的几个重大步骤有清晰的界定，能够对每个步骤的耗时作出靠谱的上界估计，你就不会被不确定的未来，不确定的时间投入感到恐惧，就不会被这种不确定感压迫到过早退出。</p></blockquote></li><li><blockquote><p>兴趣遍地都是，专注和持之以恒才是真正稀缺的。</p></blockquote></li><li><blockquote><p>饿死在干草堆之间的驴子。有很多在迷茫期的同学，迷茫都是相似的：面前有两条路，到底选哪一条？“转行还是不转行？”“学C++还是学Java。？“做管理还是做程序员？”有些问题其实不是问题：比如“学C++还是学Java。”答案是都学而且还不仅学两个。有些问题不是一个泛泛的答案能够适合的，比如转行还是不转行，需要考虑很多自身因素。但更重要的是，有人会因为无法作出决定就推迟决定，然而<strong>实际上推迟决定是最差的决定，在推迟决定期间，时间悄悄流逝，你却没有任何一条路上的积累，白白浪费了时间</strong>。</p></blockquote><p> 在迷茫的时候，不妨先保证自己手边正在做的事被做好、甚至做精。本科的时候发现周边有同学整天焦虑以后不知道干嘛，总觉得自己不知道该选择从事哪方面的工作比较好，整天散布这种焦虑的情绪，甚至持续一段时间后觉得没事可做而去花大量时间打游戏，我觉得这种情况下至少可以选择把专业课学的更深入，或者直接着手干有点感兴趣的事，而不是花大量时间去打游戏。</p></li><li><blockquote><p>一生的知识积累，自学的起码占90%</p></blockquote></li></ol><h3 id="如何有效地记忆与学习"><a href="#如何有效地记忆与学习" class="headerlink" title="如何有效地记忆与学习"></a>如何有效地记忆与学习</h3><ol><li><blockquote><p>你所拥有的知识并不取决于你记得多少，而在于它们能否在恰当的时候被回忆起来。学习新知识并将其存放于大脑中，最终的目的是要在恰当的时候能够想得起来去使用。因此，学习的有效性显然应该这样来衡量：当遇到需要用到学过的知识的时候，相关的知识是否会自动从你脑海中“蹦”出来，最起码——能否通过有意识的搜索将它们提取出来。</p></blockquote></li></ol><h3 id="学习密度和专注力"><a href="#学习密度和专注力" class="headerlink" title="学习密度和专注力"></a>学习密度和专注力</h3><ol><li><blockquote><p>真正的效率源自于内心对一个东西强烈的热忱，也就是我们俗称的追求，这时候从表层意识到深层意识都关注在这件事情上面，脑细胞高度活跃，才能创造最大的效率。为什么作诗的时候要趁着酒兴，就是因为少了这种狂热的专注，效率就低下了，<strong>一首诗作个好几天顶多是个平庸之作，跟交家庭作业也差不到哪去了</strong>。</p></blockquote></li><li><blockquote><p>专注力为什么会对学习效率造成这么大的影响。这来源于两个方面，一是专注于一件事情能让表层意识全功率运作，这个是显式的效率。第二点，也是更重要的，它还能够使你的潜意识进入一种专注于这件事情的状态。有过连续几天乃至一周或更长时间思考同一个问题的人想必都有一种感觉，就是在这个思考的期间，有时候虽然表层意识因为种种原因不在思考这个问题了（比如睡觉，比如被其它事情中断），但潜意识层面仍然保留着其“惯性”，也就是说，潜意识层面仍然在做思考的努力，从而虽然表层意识被其它事情占据，但潜意识仍然将时间无形中利用起来了。这种无形中的时间利用日积月累可以产生宏大的效应。关于后一点，著名的例子有我们熟知的那个睡觉中想出苯的化学分子式的老大。</p></blockquote></li><li><blockquote><p>关注有两种关注法，主动关注和被动关注，许多人对琐事错误的采取了主动式关注，比如常常回到家就开始想“今天还有哪些事没做完”，实际上，<strong>让这些不重要的事情自己来找你就可以了</strong>，即中断式被动关注，后者可以防止空转轮询浪费的时间，从而把最集中注意力的时间利用在最重要的事情上。</p></blockquote></li></ol><h3 id="学习习惯"><a href="#学习习惯" class="headerlink" title="学习习惯"></a>学习习惯</h3><h4 id="学习与思考"><a href="#学习与思考" class="headerlink" title="学习与思考"></a>学习与思考</h4><ol><li><blockquote><p><strong>看书挑剔，只看经典</strong>。在选择书籍的时候做足功课是对我们自己的时间负责。</p></blockquote></li><li><blockquote><p>做读书笔记。<strong>一是将自己阅读的时候的思考（包括闪念）总结下来，二是将书中的好例子摘抄下来。</strong> 我觉得，人与人学习的差距不在资质上，而在花在思考的时间和思考的深度上（后两者常常也是相关的）。</p></blockquote><p> 关于记笔记及知识的总结，其实我在两年前已经意识到记笔记的重要性。之前的发现自己花了一两周才理解的知识点，过了几个月再次遇到的时候经常不能立刻想起来，虽然能够知道这个知识点自己学过，而且遇到问题时也知道某个知识点可以用于解决遇到的问题，但是经常需要回忆很久才能记起细节，甚至需要翻书。我个人觉得是我看书后没有及时总结、做笔记，加固对知识点的理解、记忆；当然这与我自己平时看技术书籍的时候没进行相应的实践验证的坏习惯有关系。</p></li><li><blockquote><p>将思考成为习惯还有一个很大的好处——避免焦虑。感到焦虑的时候不妨思考吧，甚至完全可以去理性分析和思考导致焦虑的问题本身，将其拆解，分析来源，在不知不觉中，大脑的工作重心就从情绪模块转向了推理模块了，而且这思考也可能顺带更有效地解决了导致焦虑的问题呢</p></blockquote></li><li><blockquote><p>学习一项知识，必须问自己三个重要问题：1. 它的本质是什么。2. 它的第一原则是什么。3. 它的知识结构是怎样的。</p></blockquote></li><li><blockquote><p>人的思维天生就是极易流于表面来理解事物的（参见《Psychology of Problem Solving》第11章）。觉得自己理解了一个问题了么？条件反射性地问自己：你真的理解了吗？你真的理解了问题的本质了？ <strong>问题的本质到底是什么？目前我的理解是什么？我对这个理解感到满意吗？</strong> 这样的理解到底有什么建设性呢？等等。</p></blockquote></li></ol><h4 id="时间和效率"><a href="#时间和效率" class="headerlink" title="时间和效率"></a>时间和效率</h4><ol><li><blockquote><p>重要的事情优先（详见史蒂芬·柯维的《高效能人士的七个习惯》或《要事优先》）。<strong>尽量避免琐事骚扰，不重要的事情能不做就不做</strong>。有时候，紧急的事情往往只是当事人觉得必须马上做完才显得紧急或者干脆就是紧他人之急，最糟糕的就是纯属性格上原因觉得每件事情都得第一时间完成，很多看上去紧急的事情实际上并不是真的”不能再拖了”，有的干脆就并不需要或值得去做。有很多事情都是可以先放一放甚至完全let go的，否则的话就整天被所谓”紧急”的事情牵着鼻子走了。</p></blockquote></li><li><blockquote><p><strong>重要的事情营造比较大的时间块来完成</strong>。比如一本好书，或者一个重要的知识点，最好不要切得太琐碎了看，否则看了后面忘了前面。不利于知识的组织&amp;联系。</p></blockquote><p> 在编写代码或者调试代码时，通常不愿意被新安排的事所打断，不紧急的事通常不会立刻去处理，我通常会将其安排到本人的下一步 TODO list 中，后面闲下来时再从  TODO List 中选择待完成的事情去做。</p></li><li><blockquote><p>重视知识的本质：对于程序员来说这一点尤其重要，程序员行业的知识芜杂海量，而且总是在增长变化。很多人感叹跟不上新技术。应对这个问题的办法只能是：抓住不变量。 <strong>大量的新技术其实只是一层皮，背后的支撑技术其实都是十来年不变的东西。底层知识永远都不过时。</strong> 算法数据结构永远都不过时。基本的程序设计理论永远都不过时。良好的编码习惯永远都不过时。分析问题和解决问题的能力永远都不过时。强大的学习能力和旺盛的求知欲永远都不过时。你大脑的思维方式永远都不过时。</p></blockquote></li><li><blockquote><p>重视积累的强大力量，万事提前准备：<strong>计划订长一点，自然就可以多获得准备的时间</strong>。反之，如果不知道目的是什么，就不知道往哪个方向上使劲，就容易产生无用功。</p></blockquote><p> 单从这方面来说，长期目标还是很有用的，长期有个目标可以避免自己经常陷入迷茫的状态。</p></li></ol><h4 id="阅读方法"><a href="#阅读方法" class="headerlink" title="阅读方法"></a>阅读方法</h4><ol><li><blockquote><p><strong>趁着对一件事情有热情的时候，一股脑儿把万事开头那个最难的阶段熬过去。</strong> 万事开头难，因为从不了解到了解基本的一些事实，是一个新知识暴涨的阶段，这个时候的困难是最大的。有人熬不过去，觉得困难太大就放弃了。不过，狂热的兴趣可以抵消对困难的感觉，所以趁着对一件事情有热情的时候，开一个好头是很重要的。（当然，这并不是说持之以恒就不重要了）。当然，也许这个是因人而异的，对我来说我会在对一件事情有浓厚兴趣的时候非常专注地学习，把很多 groundworks 做掉。后面就会顺利一些了。</p></blockquote></li><li><blockquote><p>根据主题来查阅资料，而不是根据资料来查阅主题。以前读书的时候是一本一本的读，眼里看到的是一本一本的书，现在则是一章、甚至一节一节的读，眼中看到的不是一本一本的书，而是一堆一堆的章节，一个一个的知识主题，<strong>按照主题来阅读，你会发现读的时候不再是老老实实地一本书看完看另一本，而是非常频繁地从一本书跳到另一本书，从一处资料跳到另一处资料，从而来获得多个不同的人对同一个主题是如何讲解的</strong>。</p></blockquote><p> 的确，如果只从一个角度去理解一个知识点，可能永远也不会彻底掌握它。技术可能会过时，但其的确有存在的价值，至少在其被创造的时候是有某种价值的，看待某些过失的技术，不妨结合其被创造时的环境，其主要被用来解决的问题，来思考其价值，也许会更容易理解该技术的思想。</p></li><li><blockquote><p>区别好资料，坏资料。<em>好资料的特点：从问题出发；重点介绍方法背后的理念（ rationale ），注重直观解释，而不是方法的技术细节；按照方法被发明的时间流程来介绍（先是遇到了什么什么问题，然后怎样分析，推理，最后发现目前所使用的方法）。</em> 坏资料的特点是好资料的反面：上来就讲方法细节，仿佛某方法是从天上掉下来的，他们往往这样写“我们定义… 我们称… 我们进行以下几个步骤… ”。根本不讲为什么要用这个方法，人们最初是因为面对什么问题才想到这个方法的，其间又是怎样才想出了这么个方法的，方法背后的直观思想又是什么。实际上一个方法如果将其最终最简洁的形式直接表达出来往往丢失掉了绝大多数信息，这个丢掉的信息就是问题解决背后的思维过程。</p></blockquote></li><li><blockquote><p>为什么看不懂？如果看不懂一个知识，一般有如下几个可能的原因：1. 你看得不够使劲。对此古人总结过——书读百遍其义自现。2. 其中涉及到了你不懂的<strong>概念</strong>。这是技术性的不理解。这种情况就需要 Cross Reference 。如果一句话中用到了你不懂的概念，那就去查。3. <em>作者讲述的顺序不对</em>，你接着往下看，也许看到后面就明白了前面的了。</p></blockquote><p> 关于这点，我自己也常有体会。首先是平时老师上课，如果完全没预习的话，我会经常上课跟不上老师节奏，后来反思，其实是从一些概念开始跟不上老师的节奏的，后来我遇到这种情况就是，当听不懂老师讲的某个概念，而且确定是之前老师讲过的内容时，我会先跳过该知识点，而去集中听老师介绍的方法主要要解决的问题，或者算法的思路。我会经常看一些技术类书籍，有些书籍单独死磕某一段话就是搞不懂其意思，后来往后看其源代码、图表的内容，才恍然大悟。</p></li></ol><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>早就被这本书的大名所吸引，最近总算决定看一下这本书了。看了第一章，表示对文中的一些观点很赞同，因为之前自己看过基本心理学相关的书籍，思考总结时也有类似的感受（强行和大佬攀上关系.jpg 捂脸 :），只不过本人总结能力较弱，没有总结的有作者这么好。写完上面的读书笔记后，感受到了自己曾经坚持过的一些方法也是正确的，表示很开心。</p><p>拿到这本书，第一眼感觉像是作者主观色彩比较浓厚的书，平时我是比较排斥看以作者主观观点为主的书籍的。但是读了几段关于时间管理的段落后，发现文章某些内容其实是在某些心理学书上找得到依据的，感觉文章内容更像是作者看了大量书籍后，加上一定的思考和总结，写出来的。一开始觉得文章结构比较散，后来看到作者个人博客上也发表的有响应的文章，对文章结构较散这一点能够理解了，文章像是作者随笔，分享一些自己思考的结果。</p><p>恰巧本人最近在学英语，发现之前英语学的不是很好是因为自己用的比较少，而且没及时把英语学习中的一些小技巧总结下来。而且前段时间有点小焦虑，反思调整后看到这本这本书中的一些观点与自己的近期的一些感受相似，自然很开心。当然，书中的一些观点也是作者的个人观点，书中的例子也是作者自身经历的，这自然使得文章的内容更容易让人能够轻松快速地看懂，但其中的观点还是得有选择性的接受的。</p><p>由于本人看书比较慢，目前就看了第一篇。但是总的来看，此书还是不负其大名的。希望能如书中所说，保持思考！</p>]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;为何选择看这本书&quot;&gt;&lt;a href=&quot;#为何选择看这本书&quot; class=&quot;headerlink&quot; title=&quot;为何选择看这本书&quot;&gt;&lt;/a&gt;为何选择看这本书&lt;/h2&gt;&lt;p&gt;之前多次在不同地方看到有推荐看这本书，最近恰好手边没什么人文类书籍可看，在图书馆借书的时候，翻了一下此书目录，包括有关心理学、时间管理的主题，而且作者的表达简练，许多观点也比较契合本人观念，是一本适合利用琐碎时间看的书，故开始看此书。&lt;/p&gt;
&lt;p&gt;看书的时候发现，其实书中的内容作者其实也在其个人博客网站上发的有： &lt;a href=&quot;http://mindhacks.cn/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;刘未鹏 | Mind Hacks&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id=&quot;关于这个读书笔记&quot;&gt;&lt;a href=&quot;#关于这个读书笔记&quot; class=&quot;headerlink&quot; title=&quot;关于这个读书笔记&quot;&gt;&lt;/a&gt;关于这个读书笔记&lt;/h2&gt;&lt;p&gt;看此书的过程中发现许多观点其实自己也有过，只是过去没有总结、记笔记的习惯，语言表达也没有这么好。本人经常有这样的场景，脑袋里有一些想法，想记录下来的时候，发现脑袋里的一堆东西，只记下了短短几句话。嗯，总结能力欠缺！这其实也是我想要写博客的原因。看到作者也提倡记笔记，故索性写成读书笔记的形式，记录一些个人觉得精彩的语录，以及看书时所联想到的个人经历。&lt;/p&gt;
    
    </summary>
    
    
      <category term="读书笔记" scheme="https://makingl.github.io/categories/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/"/>
    
    
      <category term="暗时间" scheme="https://makingl.github.io/tags/%E6%9A%97%E6%97%B6%E9%97%B4/"/>
    
      <category term="读书笔记" scheme="https://makingl.github.io/tags/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/"/>
    
  </entry>
  
  <entry>
    <title>C++ 内存管理</title>
    <link href="https://makingl.github.io/2019/11/17/C-%E5%86%85%E5%AD%98%E7%AE%A1%E7%90%86/"/>
    <id>https://makingl.github.io/2019/11/17/C-%E5%86%85%E5%AD%98%E7%AE%A1%E7%90%86/</id>
    <published>2019-11-17T08:19:59.000Z</published>
    <updated>2019-11-17T08:35:43.157Z</updated>
    
    <content type="html"><![CDATA[<h2 id="引导语"><a href="#引导语" class="headerlink" title="引导语"></a>引导语</h2><p>在 C++ 中，内存是通过 new 表达式分配，通过 delete 表达式释放的。标准库还定义了一个 allocator 类来分配动态内存块（allocator 可以实现内存分配和对象构造的分离）。</p><p>内存的正确释放是非常容易出错的地方： 要么内存永远不会被释放（<strong>内存泄漏</strong>），要么在仍有指针引用它时就被释放了（<strong>内存的二次释放问题</strong>）。新的标准库定义了智能指针类型—— shared_ptr、unique_ptr 和 weak_ptr，可令动态内存管理更为安全。</p><a id="more"></a><p>操作系统提供的资源除了内存，还有文件描述符、互斥锁、图形界面中的字型和笔刷、数据库连接以及网络 socket。不论哪种资源，<em>当程序不再使用它时，必须将它还给系统</em>。</p><p>尝试在任何运用情况下都确保以上所言，是件困难的事，尤其当考虑到异常、函数内多重回传路径、程序维护员改动软件却没能充分理解随之而来的冲击，态势就更明显了：资源管理的特殊手段还不很充分够用。</p><h2 id="标准库提供的智能指针类型"><a href="#标准库提供的智能指针类型" class="headerlink" title="标准库提供的智能指针类型"></a>标准库提供的智能指针类型</h2><table><thead><tr><th align="center">指针类型</th><th align="center">特征</th><th align="center">特征操作</th></tr></thead><tbody><tr><td align="center">shared_ptr</td><td align="center">引用计数管理资源</td><td align="center">获得原始指针 get()</td></tr><tr><td align="center">unique_ptr</td><td align="center">某一时刻都只能有一个 unique_ptr 指向给定对象（auto_ptr 的替代品）</td><td align="center">release()、reset()；不能直接拷贝或赋值</td></tr><tr><td align="center">weak_ptr</td><td align="center">不控制所指向的对象生命周期，指向一个由 shared_ptr 管理的对象</td><td align="center">不能使用 weak_ptr 直接访问对象，而必须调用 lock() 方法</td></tr></tbody></table><p>shared_ptr 不直接支持管理动态数组，若要使用，需要提供自己定义的删除器</p><ul><li><p>与 unique_ptr 不同，shared_ptr 不直接支持管理动态数组。如果希望使用 shared_ptr 管理一个动态数组，必须提供自己定义的删除器：</p>  <figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">shared_ptr</span>&lt;<span class="keyword">int</span>&gt; sp(<span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">10</span>], [](<span class="keyword">int</span> *p) &#123;  <span class="keyword">delete</span>[] p; &#125;);   <span class="comment">// 为了使用 shared_ptr 管理动态数组，必须提供一个删除器</span></span><br><span class="line">sp.reset(); <span class="comment">// 使用指定的删除器： lambda 表达式释放数组，它使用 delete[]</span></span><br></pre></td></tr></table></figure></li></ul><h2 id="C-动态内存的实践建议"><a href="#C-动态内存的实践建议" class="headerlink" title="C++ 动态内存的实践建议"></a>C++ 动态内存的实践建议</h2><ol><li><p>以对象管理资源</p><ul><li><p>获得资源后立刻放进资源管理对象内。资源取得时机便是初始化时机（RAII， <strong>后面的 RAII 对象即是指此类对象</strong>）。</p></li><li><p>资源管理对象运用析构函数确保资源被释放。不论控制流如何离开区块，一旦对象被销毁，其析构函数自然就会被自动调用，于是资源被释放。</p></li><li><p>在以对象管理资源的情况下，如何解决二次释放的问题： 引用计数型指针。标准库提供了 shared_ptr、unique_ptr 和 weak_ptr 三种智能指针类型。</p><p>  一个类使用动态生存期的资源，可能是出于以下需求之一：</p><ul><li>程序不知道自己需要使用多少对象</li><li>程序不知道所需对象的准确类型</li><li>程序需要在<strong>多个对象间共享数据</strong></li></ul></li></ul></li><li><p>在资源管理类中小心 copying 行为</p><ul><li>复制 RAII 对象必须一并复制它所管理的资源，以资源的 copying 行为决定 RAII 对象的 copying 行为</li><li>普遍而常见的 RAII class copying 行为是： 抑制（或者禁止） copying、施行引用计数法(reference counting)</li></ul></li><li><p>在资源管理类中提供对原始资源的访问</p><ul><li>APIs 往往要求访问原始资源 (raw resource)（比如为了与 C 语言留下的接口兼容）, 所以每隔 RAII class 应该提供一个 “取得其所管理之资源”的办法</li><li>对原始资源的访问可能经由显示转换或隐式转换。一般而言显示转换比较安全，但隐式转换对客户比较方便</li></ul></li><li><p>使用智能指针时应该坚持的基本规范</p><ul><li>不使用相同的内置指针值初始化（或 release）多个智能指针</li><li>不 delete get() （shared_ptr 提供的返回原始指针的方法）返回的指针</li><li>不使用 get() 返回的指针初始化或 reset 另一个智能指针</li><li>如果使用智能指针管理的资源不是 new 分配的内存，记住传递给它一个删除器</li></ul></li><li><p>成对使用 new 和 delete 时要采取相同形式</p><ul><li>如果在 new 表达式中使用 <code>[]</code>，必须在相应的 delete 表达式中也使用 <code>[]</code>，如果在 new 表达式中不使用 <code>[]</code>，一定不要在相应的 delete 表达式中使用 <code>[]</code>。</li><li>当使用 new 时（也就是通过 new 动态生成一个对象），有两件事发生，第一，内存会被分配出来，第二，针对此内存会有一个（或更多）构造函数被调用。当使用 delete，也有两件事发生：针对此内存会有一个（或更多） 析构函数被调用，然后内存才被释放。delete 的最大问题在于： 即将被删除的内存之内究竟由多少对象？ (这个问题主要由 <code>delete</code> 和 <code>delete []</code> 以区别)</li></ul></li><li><p>以独立语句将 new 出来的对象置入智能指针</p><ul><li><p>以独立语句将 newed 对象存储于 （置入）智能指针内。如果不这样，一旦异常被抛出，有可能导致难以察觉的资源泄漏</p>  <figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">processWidget(<span class="keyword">new</span> Widget, priority());</span><br></pre></td></tr></table></figure><p>  对上面这条语句，在调用 processWidget 之前，编译器必须创建代码，做以下三件事:</p><ul><li><p>调用 priority</p></li><li><p>执行 “new Widget”</p></li><li><p>调用 shared_ptr 的构造函数</p><p>但是编译器最终执行这三条语句的顺序是不确定的，也许是下面的这种顺序：</p></li></ul><ol><li><p>执行 “new Widget”</p></li><li><p>调用 priority</p></li><li><p>调用 shared_ptr 的构造函数</p><p>如果在执行到第二条语句时发生了异常，则可能会造成在调用 processWidget 的过程中产生内存泄漏（并没有达到我们预期的用 shared_ptr 防卫内存泄漏的目的）。</p></li></ol></li></ul></li></ol><h2 id="malloc-和-delete-的区别"><a href="#malloc-和-delete-的区别" class="headerlink" title="malloc 和 delete 的区别"></a>malloc 和 delete 的区别</h2><ol><li>C 语言其实是不支持动态内存分配的，是通过 malloc 库函数来实现的，可能一些硬件不支持 malloc；而 C++ 中 <code>new</code> 是一个关键字，不管是在任意编译器上，任意硬件上，都是能够进行动态内存分配的，这是本质区别。</li><li>malloc 是基于<strong>字节</strong>来进行动态内存分配的， new 则是基于<strong>对象类型</strong>来进行动态内存分配。因此， malloc 需要自己指定申请的内存字节大小，而 new 可以不需要。</li><li>malloc 不具备内存初始化的特性，而 new 默认会调用对象的构造函数初始化分配的内存</li></ol><h2 id="如何定义一个只能在堆上（栈上）生成对象的类"><a href="#如何定义一个只能在堆上（栈上）生成对象的类" class="headerlink" title="如何定义一个只能在堆上（栈上）生成对象的类"></a>如何定义一个只能在堆上（栈上）生成对象的类</h2><p>参考链接： <a href="https://github.com/huihut/interview#如何定义一个只能在堆上栈上生成对象的类" target="_blank" rel="noopener">huihut/interview</a></p><h3 id="只能在堆上"><a href="#只能在堆上" class="headerlink" title="只能在堆上"></a>只能在堆上</h3><ul><li><p>方法</p><p>  将析构函数设置为私有</p></li><li><p>原因</p><p>  C++ 是静态绑定语言，编译器管理栈上对象的生命周期，编译器在为类对象分配栈空间时，会先检查类的析构函数的访问性。若析构函数不可访问，则不能在栈上创建对象。</p></li><li><p>实践建议</p><p>  此时 delete 也不能使用，建议将对象的构造和析构都封装成单独的函数，类似单例模式。</p></li></ul><h3 id="只能在栈上"><a href="#只能在栈上" class="headerlink" title="只能在栈上"></a>只能在栈上</h3><ul><li><p>方法</p><p>  将 new 和 delete 重载为私有</p></li><li><p>原因</p><p>  在堆上生成对象，使用 new 关键词操作，其过程分为两阶段：第一阶段，使用 new 在堆上寻找可用内存，分配给对象；第二阶段，调用构造函数生成对象。将 new 操作设置为私有，那么第一阶段就无法完成，就不能够在堆上生成对象。</p></li></ul><h2 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h2><ul><li>《C++ Primer（第五版）》[美] Stanley B.Lippman 著，王刚，杨巨峰  译</li><li>《Effective C++ （中文版 第三版）》[美] Scott Meyers 著，侯捷 译</li></ul>]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;引导语&quot;&gt;&lt;a href=&quot;#引导语&quot; class=&quot;headerlink&quot; title=&quot;引导语&quot;&gt;&lt;/a&gt;引导语&lt;/h2&gt;&lt;p&gt;在 C++ 中，内存是通过 new 表达式分配，通过 delete 表达式释放的。标准库还定义了一个 allocator 类来分配动态内存块（allocator 可以实现内存分配和对象构造的分离）。&lt;/p&gt;
&lt;p&gt;内存的正确释放是非常容易出错的地方： 要么内存永远不会被释放（&lt;strong&gt;内存泄漏&lt;/strong&gt;），要么在仍有指针引用它时就被释放了（&lt;strong&gt;内存的二次释放问题&lt;/strong&gt;）。新的标准库定义了智能指针类型—— shared_ptr、unique_ptr 和 weak_ptr，可令动态内存管理更为安全。&lt;/p&gt;
    
    </summary>
    
    
      <category term="C++" scheme="https://makingl.github.io/categories/C/"/>
    
    
      <category term="C++" scheme="https://makingl.github.io/tags/C/"/>
    
      <category term="内存管理" scheme="https://makingl.github.io/tags/%E5%86%85%E5%AD%98%E7%AE%A1%E7%90%86/"/>
    
  </entry>
  
  <entry>
    <title>博客部署完测试一下</title>
    <link href="https://makingl.github.io/2019/11/13/%E5%8D%9A%E5%AE%A2%E9%83%A8%E7%BD%B2%E5%AE%8C%E6%B5%8B%E8%AF%95%E4%B8%80%E4%B8%8B/"/>
    <id>https://makingl.github.io/2019/11/13/%E5%8D%9A%E5%AE%A2%E9%83%A8%E7%BD%B2%E5%AE%8C%E6%B5%8B%E8%AF%95%E4%B8%80%E4%B8%8B/</id>
    <published>2019-11-13T04:00:20.000Z</published>
    <updated>2019-11-13T04:16:23.528Z</updated>
    
    <content type="html"><![CDATA[<h2 id="BB-两句"><a href="#BB-两句" class="headerlink" title="BB 两句"></a>BB 两句</h2><p>花了两天时间， 弄了一下个人 GitHub Page， 其实一直想弄一个自己的博客网站的，虽然自己平时也在 CSDN 上写博客，主要是记录一些自己平时学习的笔记，方便以后自己查找，但是总觉得还是应该有个自己的博客网站，以方便自己以后将自己的笔记备份、迁移。</p><a id="more"></a><p>前两天心血来潮，网上搜了一下搭建 Github Page 的网站，确定了 Hexo + NexT 方案， 然后就一波操作，修改配置，创库、部署，一套下来真是累。</p><p>先发个文章看下效果。Cheers!</p>]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;BB-两句&quot;&gt;&lt;a href=&quot;#BB-两句&quot; class=&quot;headerlink&quot; title=&quot;BB 两句&quot;&gt;&lt;/a&gt;BB 两句&lt;/h2&gt;&lt;p&gt;花了两天时间， 弄了一下个人 GitHub Page， 其实一直想弄一个自己的博客网站的，虽然自己平时也在 CSDN 上写博客，主要是记录一些自己平时学习的笔记，方便以后自己查找，但是总觉得还是应该有个自己的博客网站，以方便自己以后将自己的笔记备份、迁移。&lt;/p&gt;
    
    </summary>
    
    
      <category term="test" scheme="https://makingl.github.io/categories/test/"/>
    
    
      <category term="测试" scheme="https://makingl.github.io/tags/%E6%B5%8B%E8%AF%95/"/>
    
  </entry>
  
</feed>
