一 Default Constructor的构建操作:
(一)两个误解:
(1)任何class如果没有定义default constructor就会合成一个。错错错!!!(Default Copy Constructor一样)
(2)编译器合成的default constructor会明确设定"class内每一个data member的默认值"。错错错!!!(Default Copy Constructor会复制其他的,如整数、指针、数组等等)。
(二)何时编译器会合成default constructor的两种说法(意思一样):
(1)ARM:当编译器需要的时候,并且合成的default constructor只满足编译器的需要。
*程序需要:由程序员完成。
*编译器需要:由编译器完成,并只满足编译器的需要,不理会程序需要。
(2)C++ Standard:当default constructor是nontrivial时,编译器会合成default constructor,合成的default constructor只满足编译器需要。
*编译器合成的default constructor中,只有base class subobjects和member class object会被初始化,所有其他non-static data member如:整数、整数指针、整数数组等都不会被初始化。
*trivial default constructor,实际上不会被合成出来。
(3)满足"编译器需要"的方法:
*合成default constructor.
*如果程序员自己定义了default constructor,则编译器会扩充已存在的constructor,在其中安插一些代码(满足编译器需要的代码),使得在user code被执行之前,先调用必要的代码满足编译器需要。
(三)是default nontrivial constructor的四种情况(即编译器会合成default constructor):
(1)"带有Default constructor"的Member Class Object。
(2)派生自"带有Default Constructor"的base class。
(3)"带有或继承一个Virtual Function"的class:编译器为object的vptr设定初值,放置适当的virtual table的地址。
(4)class派生自一个继承链,其中含有一个或多个virtual base classes:编译器安插"允许每一个virtual base class的执行期存取操作"的码。
二 Copy Constructor的建构工作:
(一)调用Copy Constructor的三种形式:
(1)类名 obj1=obj2.
(2)function(类名 obj):函数形参。
(3)function(){return obj;}:函数返回对象。
(二)Default Memberwise Initialization:
(1)概述:
*如果class没有提供一个explicit copy constructor,当object以"相同class的另一个object"作为初值时,其内部以Memberwise Initialization手法完成,即把每一个内建或派生的data member的值,从某一个object拷贝到另一个object身上,不过它并不拷贝其中member class object,而是以递归形式施行memberwise initialization.
(2)如何实现Memberwise Initialization:
*BItwise Copy实现。
*由编译器合成Copy Constructor实现。
(3)编译器何时合成Copy Constructor:
*C++ standard把Copy Constructor分为:trivial(无用)和nontrivial(有用)。
*当class不展现出bitwise copy semantics时copy constructor是nontrivial的。
*当copy construcor是nontrivial时编译器才会合成copy constructor。
(三)class不展现出Bitwise Copy Semantics的四种情况(并且如果缺乏声明的copy constructor,编译器会合成):
(1)当class内含一个member object而后者声明有一个copy constructor(无论是明确声明或被编译器合成的)时。
(2)当class继承自一个base class而后者存在一个copy constructor(无论是明确声明或被编译器合成的)。
(3)当class声明了一个或多个virtual functions时:重新设定Virtual Table的指针。两种情况:
*一个对象以另一个相同类的对象作为初值:bitwise copy就可以。例如:基类<->基类、派生类<->派生类。
*一个基类对象以派生类的对象作为初值:编译器必须合成copy constructor明确设定基类对象的vptr指向的virtual table。
(4)当class派生自一个继承链,其中有一个或多个virtual base classes时:处理Virtual Base Class Subobject。两种情况:
*一个对象以另一个相同类的对象作为初值:bitwise copy就可以。例如:基类<->基类、派生类<->派生类。
*一个基类对象以派生类的对象作为初值:编译器必须合成copy constructor明确设定virtual base class pointer/offset的初值。
三 Copy assignment operator:
(一)class不展现出Bitwise Copy的四种情况
1.当class内含一个member object,而其class由一个copy assignment operator时。
2.当一个class的base class有一个copy assignment operator.
3.当一个class声明了任何virtual functions时。
4.当class继承自一个virtual base class时。
(二)在以上四种情况下(即class不展现bitwise copy)编译器会合成copy assignment operator。
四 destructor:
(一)编译器合成析构函数的情况:
1.class没有定义destructor,只有在class内含的member对象或class自己的base class拥有destructor的情况下,编译器才会自动合成。其他情况不合成(例如:具有虚函数也不合成)
五 程序转化语意学
六 成员初始化队列(Member Initialization List):
(一)必须使用member initialization list的情况:
1.初始化一个reference member时。
2.初始化一个const member时。
3.调用一个base class的constructor,而它拥有一组参数。(constructor包括:构造函数和复制构造函数)
4.调用一个member class的constructor,而它拥有一组参数。
(二)对于非内置类型,成员初始化列表效率高。
*构造函数体内成本:default constructor+operator =
*初始化列表:copy constructor。
(三)初始化列表中的顺序:
*编译器按照members在class中的声明次序对初始化列表一一处理,而不是按照初始化列表中的排列次序。