《深度探索C++对象模型》第2章 构造函数语意学

1.Default Constructor(默认构造函数,即没有明显实参的函数的构造情况

C++编译器在以下4种情况下默认构造函数会被认为是nontrival(有用的),需要由编译器合成出来,只执行编译器所需要的行为:

①含有类对象数据成员,且该成员有默认构造函数;

②基类带有默认构造函数的派生类;

①与②相似,假如类内的普通data member也需要初始化,就需要明确定义构造函数 => 扩张构造函数:先(按声明或继承顺序)调用类成员变量的默认构造函数,在初始化其它data member。

③带有虚函数的类;

不管是自身声明的还是继承得来的虚函数,都会发生两个扩展:(1)类编译时,编译器会产生一个vbtl,内放虚函数地址;(2)对象编译时,编译器会产生一个vptr,指向vbtl。其中,vbtl为虚函数表,vptr为虚函数表指针。

此外,虚函数的调用会被改写,如:widget.filp(); -----> (*widget.vptr[1])(&widget);   &widget为this指针

④虚继承下的类;

与③类似,需初始化虚基类指针。

当然,如果程序有需要,程序员需要自己手动编写类的default constructor。

两个误解:


2.Copy Constructor的构造操作

拷贝构造的默认做法是逐个成员拷贝(memberwise initialization),也就是把对象中每一个内建或派生的data member拷贝到另一个对象中,不过对于其中的member class object,不会直接拷贝,而是递归实现。

这种递归的memberwise initialization是如何实现的呢?答案就是Bitwise Copy Semantics或default copy constructor。

Bitwise Copy Semantics(位逐次拷贝)就是将源类中的成员变量中的每一个都逐次复制到目标类,这时,对指针变量来说就存在问题,指针变量复制了源类中的值,一旦源类开辟的内存空间释放,目标类的该指针就指向了被释放的空间,成为了悬空指针(这就是浅拷贝吧)。

 

问:编译器在什么情况下产生拷贝构造函数?(即不展现bitwise copy semantics,而使用default copy constructor)

答:

同默认构造函数的四点。

因为在①②情况下,编译器必须将member或base class的 copy constructor 的调用操作安插到被合成的 copy constructor中;

而在③情况下,因为class含有virtual function,编译时需要进行扩张操作:增加vbtl并在class object中创建vptr,这样才能保证vptr被正确地赋值了,否则就去执行其它class的virtual function了;

对于情况④,每一个编译器对于虚拟继承的支持承诺,都是表示必须让“derived class object中的virtual base class subobject位置”在执行期就准备妥当,维护“位置的完整性”是编译器的责任。Bitwise Copy Semantics可能会破坏这个位置,所以编译器必须自己合成出copy constructor。


该Point3d的copy constructor是trivial(无用的),初始化操作会采用bitwise copy,这样效率高且安全,并不需要显式定义拷贝构造函数。

但如果有大量成员变量,可以手动定义copy constructor进行memberwise初始化操作,效率更高,如:

若使用memcpy()或memset(),效率更高:


3.初始化成员列表

以下四种情况,需要(必需)通过初始化成员列表进行参数初始化:

①初始化一个reference member时;

②初始化一个const membert时;

③调用一个base class的constructor,而它拥有一组参数时;

④调用一个member class的constructor,而它拥有一组参数时。

总的来说就是,所有需要定义时初始化的都需要初始化列表

因为会将代码扩张,产生临时对象——先调用默认构造,再调用赋值函数。

对于内置类型效率差别不大, 但对于类类型最好使用初始化列表——可以直接调用拷贝构造。


  • list中初始化的顺序是由class中member的声明顺序决定的,编译器会按照这种顺序对list重排,所以下面的程序会出错:

  • list中的成员初始化放在explicit user code之前,如下正确:

  • list中可以用可以调用成员函数初始化成员变量,如下正确:


参考博客:

posted @ 2023-05-02 17:14  Hell0er  阅读(21)  评论(0)    收藏  举报