读书笔记 《深度探索c++对象模型》 (1)

第二章:构造函数语意学
2.1 default constructor的构建操作
c++标准说:对于class X,如果没有任何程序员声明的构造函数,那么编译器会implicitly(暗中)合成出一个trivial(无能的,没啥用的)构造函数。
(备注:global objects的内存在程序激活的时候会被清0。local objects位于程序的堆栈中,heap objects位于自由空间中,都不一定会被清0。它们的内容是内存上次被使用之后的遗迹。)
但是,有四种情况,这个被implicitly合成出的函数,会是nontrivival(有用的)。
a)带有default constructor的member class object
例如: 被合成的class B的default constructior内含有必要的代码,这些代码调用了class A的default constructor。但是,并不会产生初始化i的代码。所以说,被合成的default constructor只符合编译器的需要,不符合程序员的需要。
如果B已经有程序员定义的构造函数,那么每个构造函数都会被编译器扩张,在其中安插一些代码,这些代码在user code执行之前,会调用必要的default constructor。并且,如果class B中有多个class member objects需要constructor的初始化操作。那么c++会按照声明的顺序来调用各个constructor。例如: class D的构造函数会被扩展成: b)带有default constructor的base class
类似,如果一个没有任何constructor的class派生自一个带有default constructor的基类,那么一个nontrivial的constructor会被合成出来。它将调用上层基类的default constructor(按照声明的次序)。
如果程序员提供了多个constructor,但是没有default constructor,那么每一个constructor都会被扩张会将调用基类default constructor的代码加进去。如果同时存在带有default constructor的member class object,那么这些member的default constructor也会被调用——在所有base class constructor被调用之后。
c)带有一个virtual function的class
我们知道,一个带有virtual function的class的每一个object中,一个vptr会被合成出来,内含相关class vtbl的地址。为了让多态的机制发挥功效,编译器会为vptr设定初始值。对于每一个constructor,它们会被安插一些代码来做这件事情。如果没有声明任何constructor,那么合成的default constructor会初始化每一个class object的vptr。
d)带有virtual base class的class
virtual base class的实现在不同的编译器中有很大的差异。但是它们的共同点是:必须使每一个virtual base class 在其每一个derived class object中的位置,必须在执行期准备妥当。
编译器是无法决定foo中i的偏移位置的。因为pa的真正类型在执行期间可以改变。所以编译器必须改变一些代码使得X::x的位置可以在执行期才被决定。一种做法是:在derived class object的每一个virtual base class中安插一个指针,表示在当前object中,该virtual base class的位置。 __vbcX是编译器产生的指针,指向virtual base class X。这个指针是在编译时期构建的。对于class定义的每一个constructor,编译器会安插那些“允许每一个virtual base class的执行期存取操作”的代码。如果class没有声明任何constructor,那么编译器会合成一个default constructor来做这些事情。这个default constructor就是nontrivial的。
c)和d)其实是差不多的,分别是初始化virtual function机制和virtual base class机制。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值