Effective C++
文章平均质量分 66
详细研读Effective C++后,根据个人的掌握情况以及结合之前的时间经验,总结出一系列值得关注和讨论的问题。
奋起的熊猫
热爱技术即是正义!
展开
-
条款14:在资源管理类中小心copying行为
如果前述的Lock打算使用 reference counting,他可以改变mutexPtr的类型,将它从Mutex* 改为 shared_ptr。然而很不幸shared_ptr的缺省行为是“当引用次数为0时闪促其所指物”,那不是我们想要的行为。而mutexPtr的析构函数会在互斥器的引用次数为0时自动调用shared_ptr的删除器(本例为unlock)。幸运的是shared_ptr允许指定所谓的“删除器”(deleter),那是一个函数或函数对象,当引用次数为0时便被调用。如何将这个概念表现在。原创 2023-07-18 19:32:11 · 54 阅读 · 0 评论 -
条款13: 以对象管理资源
先通过一段小白的代码案例引入主题。一如以上注释所言,createInvestment的调用端使用了函数返回的对象后,有责任删除之。这看起来似乎妥当,但——1)或许因为“…”区域内的一个过早的return语句。如果这样一个return被执行起来,控制流就绝不会触及delete语句;2)类似情况发生在对createInvestment的使用及delete动作位于某循环内,而该循环由于某个continue或goto语句过早退出;原创 2023-07-16 10:25:32 · 275 阅读 · 0 评论 -
第三章 资源管理导读
C++程序中最常使用的资源就是动态分配内存(如果你分配内存却从来不曾归还它,会导致内存泄漏),但内存只是你必须管理的众多资源之一。不论哪一种资源,重要的是,当你不再使用它时,必须将它还给系统。这些排列在后的专属条款弥补了先前一般化条款的不足,因为管理内存的那个对象必须知道如何适当而正确地工作。尝试在任何运用情况下都确保以上所言,是件困难的事,但当你考虑到异常、函数内多重回传路径、程序维护员改动软件却没能充分理解随之而来的冲击,态势就很明显了:资源管理的特殊手段还不很充分够用。原创 2023-07-15 18:00:21 · 45 阅读 · 0 评论 -
条款12: 复制对象时勿忘其每一个成分
本条款看似很直白,但其中确实有不易识别的坑。本节先给出相关结论,然后通过几个案例引出问题,并给出解决方案。如果声明了自己的copying函数,意思是告诉编译器你并不喜欢默认实现中的某些行为。编译器仿佛被冒犯似的,会以一种奇怪的方式回敬:当你的实现代码几乎必然出错时却不告诉你。原创 2023-07-15 16:37:05 · 45 阅读 · 0 评论 -
条款11: 在operator=中处理“自我赋值”
首先通过一个案例来引入下面是operator=实现代码,表面上看起来合理,但是自我赋值时并不安全。原创 2023-07-06 18:05:50 · 57 阅读 · 0 评论 -
条款10: 令operator= 返回一个reference to *this
该协议不仅适用于以上标准赋值形式,也适用于所有赋值相关运算,例如:+=、-=、*=等等。原创 2023-07-05 22:18:52 · 48 阅读 · 0 评论 -
条款09:绝不在构造和析构过程中调用virtual函数
—即使目前即将建立的对象类型是BuyTransaction。是的,base class构造期间virtual函数绝不会下降到derived class阶层。取而代之的是,对象的作为就像隶属base类型一样。非正式的说法也许比较传神:在base class构造期间,virtual函数不是virtual函数。这一似乎反直觉的行为有个好理由。由于base class构造函数的执行更早于derived class构造函数,当base class构造函数执行时derived class的成员变量尚未初始化。原创 2023-07-05 22:04:18 · 51 阅读 · 0 评论 -
条款08: 别让异常逃离析构函数
C++不喜欢析构函数吐出异常。但如果你的析构函数必须执行一个动作,该动作可能会在失败时抛出异常,该怎么办?为了确保客户不忘记在DBConnection对象身上调用close(),一个合理的想法时创建一个用来管理DBConnection资源的class,并在其析构函数中调用close。只要调用close成功,一切都美好。但如果调用导致异常,DBConn析构函数会传播该异常,也就是允许它离开这个析构函数。那会造成问题,因为造成了难以驾驭的麻烦。有两个解决方案可以避免这一问题。原创 2023-07-05 01:06:54 · 36 阅读 · 0 评论 -
条款07: 为多态基类声明virtual析构函数
结论:设计一个TimeKeeper base class和derived class作为不同的计时方法,如下代码:许多客户指向在程序中使用时间,不想操心时间如何计算细节,这时候我们可以设计factory(工厂)函数,返回指针指向一个计时对象。Factory函数会“返回一个base class指针,指向新生成的derived class对象”:为遵守factory函数的规矩,被getTimeKeeper()返回的对象必须位于heap。因此为了避免泄漏内存和其它资源,将factory函数返回的每一个对象释放原创 2023-07-04 23:29:50 · 48 阅读 · 0 评论 -
条款06: 若不想使用编译器自动生成的函数,就该明确拒绝
为驳回编译器自动提供的机能,可将相应的成员函数声明为private并且不予实现。原创 2023-07-04 20:02:51 · 71 阅读 · 0 评论 -
条款05: 了解C++默默编写并调用了哪些函数
什么时候empty class不再是个空类了呢?当C++处理它之后。如果自己没有声明任何函数,C++编译起会为空类声明一个默认的构造函数、析构函数、拷贝构造函数和拷贝复制操作符。所有的这些函数均是public且inline的。只有当这些函数被调用,它们才会被编译创造出来;如果类中已有构造函数,则无须担心编译器会给生成默认的无参构造函数。注意:编译器产出的析构函数是个non-virtual。原创 2023-07-03 20:12:44 · 31 阅读 · 0 评论 -
条款04: 确定对象在使用前已被初始化
这些函数“内含static对象”的事实使他们在多线程系统中带有不确定性。原创 2023-07-03 18:55:18 · 51 阅读 · 0 评论 -
条款03:尽可能使用const
本文阐述了const使用场景,以及需要格外注意的事项。并讨论了3个比较有意思的小topic。原创 2023-06-29 20:21:06 · 51 阅读 · 0 评论 -
【Effective C++】导读
你该选择inheritance(继承)还是templates(模版)?该选择member函数还是non-member函数?该选择pass-by-value还是pass-by-reference。本书的最佳用途就是彻底了解C++如何行为、为什么那么行为,以及如何运用其行为形成优势。本书提供的忠告大致分为两位:一般性的设计策略,和带有具体细节的特定语言特性。设计上的讨论集中于“如何在两个不同的做法中选择完成某项任务”。取乎其中,得乎其下;本书的目的是告诉你如何有效运用C++。本书提供的语言的使用引导,原创 2023-06-28 21:28:58 · 37 阅读 · 0 评论 -
Effective C++改善程序与设计的55个具体做法---专栏介绍
当时,师父给我的设计提了这些方面的意见和改进点,但是当时自己实在不懂具体是什么意思,工作过程中也并没有额外的时间供自己去了解这些,因此,当时只是完成了基本功能,确保基本功能以及内存大小和效率上的保障。至于异常安全函数的强烈保证,自己在实现需求的过程中有考虑,但是实现起来自认为没有可操作性而且太繁琐,因此放弃了一开始的想法,只对程序异常处理做了基本承诺。在阅读的过程中,产生了诸多感悟,有的地方让自己醍醐灌顶,因此想写一系列精品小文来记录一些值得分享的技术点和感悟。原创 2023-06-28 21:05:55 · 31 阅读 · 0 评论