ct以另一个同类object作为初值,而是发生于一个class object以其derived classes的某个object作为初值.例如让Racccon object以一个RedPanda object作为初值,而RedPanda声明如下:
class RedPanda : public Raccon {
public:
RedPanda() { /* 设定private data初值 */ }
RedPanda(int val) { /*设定private data初值 */ }
private:
// ...
};
如果以一个Reccon object作为另一个Raccon object的初值,那么bitwise copy就戳戳有余了
// 简单的bitwise copy就足够
Raccon rocky;
Raccon little_critter = rocky;
然而
如果企图以一个RedPanda object作为little_critter的初值,编译器必须判断后续当程序员企图存取其ZooAnimal subobject时是否能够正确地执行
// 简单的bitwise copy还不够
// 编译器必须明确地将litte_critter的virtual base class pointer/offset初始化
RedPanda little_red;
Raccon little_critter = little_red;
在这种情况下,
为了完成正确的little_critter初值设定,编译器必须合成一个copy constructor,插入一些码以设定 virtual base class pointer/offset的初值,对每一个members执行必要的memberwise初值化操作,以及执行其它的内存相关操作(3.4对于 virtual base classes有更详细的讨论)
在下面的情况中,编译器无法知道是否bitwise copy semantics还保持着,因为它无法知道Raccon指针是否指向一个真正的Raccon object,还是指向一个derived class object:
// 简单的bitwise copy可能够用,可能不够用
Raccon *ptr;
Raccon little_critter = *ptr;
当一个初始化操作存在并保持着bitwise copy semantics的状态时,如果编译器能够保证object有正确而相等的初始化操作,是否它应该抑制copy constructor的调用,以使其所产生的程序代码优化?
至少在合成的copy constructor之下,程序副作用的可能性是零,所以优化似乎是合理的。如果copy constructor是由 class 设计者所提供的呢?这是一个颇有争议的问题。
上面介绍的四种情况下 class 不再保持bitwise copy semantics,而且 default copy constructor如果未被声明的话,会被视为nontrivial,在这四种情况下,如果缺乏一个已声明的copy constructor,编译器为了正确处理一个class object作为另一个class object的初值,必须合成出一个copy constructor。下一节介绍编译器调用ocpy constructor的策略,以及这些策略如何影响程序。
?