[读书笔记] 深入探索C++对象模型-第二章《构造函数语义学》(中)

继续整理第二章的内容,是关于拷贝构造函数的。

1. 有三种情况会以一个对象的内容作为另一个类对象的初始值:

a. 明确的以一个对象初始化另一个对象,例如: A a1 = a2;//会调用类A的拷贝构造函数初始化a1。

b. 对象被作为参数传递给某个函数时:foo(A a){...}; A a1; foo(a1);//a1作为参数的初值。

c. 当传回一个类对象时,A foo() {A a1; return a1;}。

 2. 编译器是否会合成拷贝构造函数,取决于程序是否展现出按位拷贝语义(bitwise copy semantic),如果展现出该语义那么,编译器并不会合成拷贝构造函数,而是按成员初始化(member wise initialization),即递归的将所有数据成员依次赋值。书中的例子如下:


如果程序未展现该语义,那么编译器会合成拷贝构造函数,如下四种情况会合成拷贝构造函数(即展现非bit wise copy semantic):

a. 类中包含含有拷贝构造函数(不论该拷贝构造是明确声明的还是编译器合成的)的数据成员。

b. 当类继承自含有拷贝构造函数(不论是明确声明的还是编译器合成的)的基类。

这两种情况系统会将该数据成员或者基类的拷贝构造函数安插到合成的拷贝构造函数中。

c. 当类声明了多个虚函数。编译器必须为通过拷贝构造的对象正确的初始化虚表指针,这种情况发生于当子类对象拷贝到父类对象中时,例如,当子类对象yogi拷贝到父类对象franny(父类是值对象,而不是指针和引用,后两种情况会产生多态行为)中时,必须为franny初始化合适的虚表指针,而不能通过按成员初始化(member wise initialization),所以必须合成一个构造函数,安插相关代码到其中执行这个修改


d. 当类派生自一个继承串链,其中有一个或者多个虚基类时。与上一种情况类似,编译器必须保证子类中虚基类子对象位置的确定性,而按位拷贝可能会破坏这个位置信息,尤其是当子类对象拷贝到父类对象中时,编译器必须合成一个拷贝构造函数进行正确的处理,例如,此种情况下,编译器必须合成一个拷贝构造函数,安插一些代码,设定虚基类指针或者偏移量,对每一个成员执行必要的member wise initialization以及其他内存相关工作(第三章虚基类部分会由详细介绍)


总的说起来,与合成默认构造函数类似,合成拷贝构造函数只有在编译器需要的情况下才会发生。例如编译器需要调用某些拷贝构造函数,这些调用代码必须被安插到本类的拷贝构造函数中,如果本类没有拷贝构造,则必须要为其合成一个,又或者需要在拷贝构造函数中进行一些指针的初始化操作。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值