C++:编译器合成默认构造函数和复制控制成员的条件
(参考自《深入理解C++对象模型》)
”C++新手一般有两个常见的误解:
任何class如果没有定义default constructor,就会被合成一个出来.
编译器合成出来的default constructor会明确设定class 内每一个data member的默认值.”
现在主要解释第一条为什么是错误的,根据《深入理解C++对象模型》,”default constructor 在需要的时候被编译器产生出来”,以下就是4种”需要的时候”:
1). 该类含有一个成员对象而后者有一个默认构造函数.
如果一个类没有任何构造函数,但它含有一个成员函数,这个成员函数含有默认构造函数,那么编译器就需要为这个类合成一个默认构造函数并调用那个成员的默认构造函数.
2). 该类继承自一个基类且后者带有默认构造函数.
原理和1)类似
3). 该类带有一个虚函数
编译器需要合成一个默认构造函数并在编译期发生两种扩张操作:”一个virtual function table(在cfront中被称为vtbl)会被编译器产生出来,内放class的virtual function地址”,”在每一个class object中,一个额外的pointer member(也就是vptr)会被编译器合成出来,内含相关的class vtbl地址”.
4). 该类派生自一个继承串链,其中有一个或多个虚基类
不同编译器对虚基类的实现不同,但编译器需要合成一个默认构造函数并改变对虚基类”执行存取操作”的那些码,使得对虚基类的操作延迟至执行期才决定下来.
同理,如果类没有定义拷构造函数,那么编译器会视该类有没有展现”bitwise copy semantics“(位逐次拷贝语义来决定是否合成拷贝构造函数),在以下四种情况下类不展现出”bitwise copy semantics“:
1). 该类含有一个成员对象而后者有一个拷贝构造函数.
2). 该类继承自一个基类且后者带有拷贝构造函数.
3). 该类带有一个虚函数
4). 该类派生自一个继承串链,其中有一个或多个虚基类
可见,编译器在类没有定义拷贝构造函数时合成拷贝构造函数的要求与默认构造函数类似,唯一不同的是如果编译器不合成默认构造函数,那么将不会对成员进行任何初始化操作,如果编译器不合成拷贝构造函数,那么将会进行”bitwise copy”(位逐次拷贝,按位逐位拷贝),如果成员有指针,那么位逐次拷贝进行的是浅复制.