1. 如果一个class没有任何constructor,但它内含一个member object,并且该member object有default constructor,那么这个class的implicit default constructor就是“nontrivial”,编译器需要为该class合成一个default constructor。不过这个合成操作只有在constructor真正需要被调用时才发生。
2. 在C++各个不同的编译模块中,编译器如何避免多个default constructor呢? 解决方法是把合成的default constructor, copy constructor, destructor, assignmen copy operator都以inline方式完成。一个inline函数有静态链接,不会被文件以外者看到。如果函数太复杂,不适合做成inline,就会合成一个explicit non-inline static实例。
3. C++语言要求以“member objects在class中的声明顺序”来调用各个constructor。
4. 如果一个没有任何constructor的class派生自一个“带有default constructor”的base class,那么这个derived class的default constructor会被视为“nontrivial”,并因此需要被合成出来。
5. 以下两种情况也需要合成出default constructor:
i. class声明(或继承)一个virtual function;
ii. class派生自一个继承串链,其中有一个或更多的virtual base class。
编译器在此期间会做:
a. 一个virtual function table会被编译器产生出来,内放class的virtual functions地址;
b. 在每一个class object中,一个额外的pointer member(也就是vptr)会被编译器合成出来,内含class vtbl的地址。
对于那些未声明任何constructor的classes,编译器会为它们合成一个default constructor,以便正确地初始化每一个class object的vptr。
6. 两个误解:
i. 任何class如果没有定义default constructor,就会被合成一个来。
ii. 编译器合成出来的default constructor 会显式设定“class 内每一个data member的默认值”。
7. 复制构造函数。
i. type a, b; a = b。
ii. 作为函数参数被调用(非引用和指针类型)。
iii. 作为函数的返回值被返回。
8. copy constructor是当class不展现“bitwise copy semantics”时,才由编译器产生出来。
9. 构造出来default copy constructor有效的情形跟default constructor一直。(见1,4,5)
10. 对于copy constructor,不管使用memcpy还是memset,都只有在“class不含任何编译器产生的内部members”时才能有效运行。
11. 必须使用member initialization list的情况:
i. 当初始化一个reference member时;
ii. 当初始化一个const member时;
iii. 当调用一个base class的constructor,而它拥有一组参数时;
iX. 当它调用一个member class的constructor,而它拥有一组参数时。