Effective C++ 读书笔记之Part2.Constructors, Destructors, and Assignment Operators

5.Know what functions C++ silently writes and calls.

总结:编译器可以暗自为class创建default构造函数、copy构造函数、copy assginment操作符,以及析构函数。这些函数都是public的,并且是inline的。

6.Explicitly disallow the use of compiler-generated functions you to not want.

总结:为驳回编译器自动(暗自)提供的机能,可将相应的成员函数声明为private并且不予实现。使用像Uncopyable这样的base class也是一种做法。

该条目主要是通过将copy 和copy assignment两个函数,声明为private并且不实现函数,这样编译器就不会默认产生这两个函数,并且也避免了对这两个函数的直接调用。

7.Declare destructors virtual in polymorphic base classes.

总结:

第一,polymorphic(带多态性质的)base classes 应该声明一个virtual析构函数。如果class带有任何virtual函数,它就应该拥有一个virtual析构函数。

第二,classes的涉及目的如果不是要作为base classes使用,或者不是为了具备多态性(polymorphically),就不该声明virtual析构函数。

8.Prevent exception from leaving destructors.

总结:

第一,析构函数绝对不要吐出异常。如果一个被析构函数调用的函数可能抛出异常,析构函数应该捕捉任何异常,然后吞下他们(不传播)或结束程序。

第二,如果客户需要对某个操作函数运行期间抛出的一场作出反应,那么class应该提供一个普通函数(而非在析构函数中)执行该操作。

9.Never call virtual functions during construction or destruction.

总结:

在构造和析构期间不要调用virtual函数,因为这类调用从不下降致drived class(比起当前执行构造函数和析构函数那层)。

如果实在是想调用,则可以使用drived classes将必要的构造信息向上传递至base class构造函数。但是这时候调用的函数应改为非virtual函数。

10.Have assignment operators return a reference to *this.

总结:

令赋值(assignment)操作符返回一个reference to *this.

11. Handle assignment to self in operator=.

总结:

第一,确保当前对象自我赋值时operator=有良好行为。其中技术包括比较“来源对象”和“目标对象”的地址、精心周到的语句顺序、以及copy-and-swap。

第二,确定任何函数如果操作一个以上的对象,而其中多个对象是同一个对象时,其行为仍然正确。

12. Copy all parts of an object.

如果自己写copy函数,其中有部分成员未被copy,编译器不会提醒。即使是在最高的警告级别中。

总结:

第一,copying 函数应该确保复制“对象内的所有成员变量”及“所有base class成分”。

第二,不要尝试以某个copying函数实现另一个copying函数。应该将共同机能放进第三个函数中,并由两个copying函数共同调用。

感想:这部分内容主要是关于构造函数和析构函数的。因为编译器会默认给class生成构造函数、析构函数、copy和copy assignment函数。所以这就引出了一系列的问题,如果避免别人调用系统生成的这些函数而犯错,如何自己构造这些函数,构造这些函数的时候需要注意哪些问题。这些内容就构成了本部分的全部内容,提到的这些点确实是平时很容易犯错的点,学习了之后,很有利于提高代码的质量。

时间: 2024-12-04 00:05:45

Effective C++ 读书笔记之Part2.Constructors, Destructors, and Assignment Operators的相关文章

More Effective C++ 读书笔记四——异常

条款9:利用destructors避免泄漏资源 这里开始介绍了auto_ptr,其实就是利用了c++局部对象在离开作用域的时候,其析构函数会被调用,来避免资源泄漏.这样的好处,就是不管是作用域正常结束(跑出代码块)还是异常结束(抛出异常),对象的析构函数都能保证被调用. 条款10:在constructors内阻止资源泄漏 c++只会析构已构造完成的对象.对象只有在其constructor执行完毕才算是完全构造妥当. 也就是说,c++不自动清理那些"构造期间抛出exceptions"的对

More Effective C++ 读书笔记五——异常

条款12:了解"抛出一个exception"与"传递一个参数"或"调用一个虚函数"之间的差异 第一,exception object总是会被复制,如果以by value方式捕捉,它们甚至被复制两次.至于传递给函数参数的对象不一定得复制.第二,"被抛出成为exceptions"的对象,其被允许的类型转换动作,比"被传递到函数去"的对象少.第三,catch子句以其"出现于源代码的顺序"被编译

More Effective C++ 读书笔记二

条款4:非必要不提供default constructor 这里主要是列举下默认构造函数的优点和缺点. 如果没有默认构造函数,定义对象数组会比较麻烦,因为对象数组初始化的时候没法传递非默认构造函数的值,如果要使用,书中提到的方法是给数组每个变量初始化的时候调用构造函数,另一个就是使用指针数组. 第一个的缺点很明显,没法声明类似A a[10];这样的数组,在堆上申请,还得用到placement new这个之前没讲过的东西,另外还得一个个去初始化:后者的缺点当然是,数组里面的每个指针都需要记得去de

Effective C++ 读书笔记之Part1.Accustoming Yourself to C++

1.View C++ as a federation of languages C++的四个次语言: 1)C 2)Object-Oriented C++ 3)Template C++ 4)STL 2.Prefer consts, enums, and inlines to #defines 一方面是因为使用宏定义不利于调试的时候定位错误,另一方面主要是因为预处理器和编译器两者分工不同所导致的. 同时,宏定义太复杂的情况下很容易出现错误. 总结: 第一,对于单纯常量,最好以const对象或enum

Effective C++ 读书笔记之Part6.Inheritance and Object-Oriented Design

32.Make sure public inheritance models "is-a". 所谓的最佳设计,取决于系统希望做什么事,包括现在与未来. 需要解决的问题:其中关于两个assert都通过的地方有些疑惑. 总结: "public继承"意味着is-a.适用于base classes身上的每一件事情一定也适用于derived classes身上,因为每一个derived class对象也都是一个base class对象. 33.Avoid hiding inh

More Effective C++ 读书笔记六——临时对象

条款19:了解临时对象的来源 c++真正的所谓的临时对象是不可见的--不会再你的源代码中出现.此等匿名对象通常发生于两种情况:一是当隐式类型转换(implicit type conveersions)被施行起来以求函数调用能够成功:二是当函数返回对象的时候. 第一种情况的例子: [cce lang="cpp"] #include <iostream> class Int { public: Int(int value) { _value = value; std::cout

More Effective C++ 读书笔记三

条款8:了解各种不同意义的new和delete 这里讲了3种new,分别是:new operator, operator new, placement new. new operator最简单,它就是我们平时常用的new关键字,需要注意的是,它是不能被重载的.new operator的语义是先分配内存,然后调用对象的构造函数. operator new:这个是这三个new里面唯一能够重载的,平时我们重载的就是这个操作符.它的声明是: [cc lang="cpp"] void *oper

Effective C++ 读书笔记之Part5.Implementations

 26. Postpone variable definitions as long as possible. 总结: 尽可能延后变量定义式的出现.这样做可增加程序的清晰度并改善程序效率. 批注: 纯C语言此处有冲突,C语言要求变量定义出现在代码快的开始部分. 27. Minimize casting. 1)const_cast 通常被用来将对象的常量性转除(cast away the constness) .它也是唯一有此能力的 C++-style 转型操作符. 2)dynamic_cast主

Effective C++ 读书笔记之Part8.Customizing new and delete

49. Understand the behavior of the new-handler. 总结: 第一,set_new_handler允许客户指定一个函数,在内存分配无法获得满足时被调用. 第二,Nothrow new是一个颇为局限的工具,因为它只适用于内存分配:后继的构造函数调用还是可能抛出异常. 50. Understand when it makes sense to replace new and delete. 替换编译器提供的operator new或operator dele