The Semantics of Constructors——2.2 拷贝构造函数的构造操作

The Semantics of Constructors

2.2.1 Default Memberwise Initialization(默认的逐成员初始化)

如果class没有提供一个explicit copy constructor又当如何?当class object 以“相同 class 的另一个 object”作为初值,其内部是以所谓的 default memberwise initialization手法完成的,也就是把每一个内建的或派生的data member(例如一个指针或一个数组)的值,从某个object拷贝一份到另一个object身上。不过它并不会拷贝其中的 member class object,而是以递归的方式施行 memberwise initialization。

copy constructors在必要的时候才由编译器产生出来。这个句子中的“必要”意指当 class 不展现 bitwise copy semantics 时。

2.2.2 什么时候不会Bitwise Copy Semantics(位逐次拷贝)?

(什么时候编译器会合成copy constructors呢?)

什么时候一个class不展现出“bitwise copy semantics”呢?有4种情况:

  1. 当class内含一个member object 而后者的class声明有一个copy constructor时(不论是被 class设计者显式地声明,就像前面的 String那样;或是被编译器合成,像 class Word那样)。

  2. 当 class继承自一个 base class而后者存在一个 copy constructor时(再次强调,不论是被显式声明或是被合成而得)。

  3. 当 class声明了一个或多个 virtual functions时。

  4. 当 class派生自一个继承串链,其中有一个或多个 virtual base classes时。

在前两种情况中,编译器必须将member或base class的“copy constructors调用操作”安插到被合成的copy constructor 中。

2.2.3 重新设定 Virtual Table的指针

1. 同类型之间的拷贝

//Bear有虚函数
Bear yogi;
Bear winnie  = yogi;

会直接把yogi的vptr值拷贝给winnie,两个对象的虚函数指针指向相同的虚函数表。

2. 用派生类初始化基类


//ZooAnimal 是Bear的基类
ZooAnimal franny = yogi; //会发生sliced

合成出来的ZooAnimal copy constructor 会显式设定object的vptr指向ZooAnimal class的virtual table,而不是直接从右手边的class object中将其vptr现值拷贝过来。

2.2.4 处理 Virtual Base Class Subobject

虚基类——Raccoon

虚基类的派生类——RedPanda

  1. 如果用一个虚基类Raccoon对象初始化另一个Raccoon对象,那么直接“bitwise copy”就可以了。

  1. 如果用一个虚基类的派生类RedPanda对象初始化一个Raccoon虚基类时:在这种情况下,为了完成正确的 little_critter 初值设定,编译器必须合成一个copy constructor,安插一些代码以设定virtual base class pointer/offset 的初值(或只是简单地确定它没有被抹消),对每一个members执行必要的memberwise初始化操作,以及执行其他的内存相关工作

little_red和little_critter的关系:

posted on 2023-02-07 00:31  七昂的技术之旅  阅读(25)  评论(0编辑  收藏  举报

导航