C++ copy constructor 构建

最近在看《深度探索C++对象模型》一书,里面讲到了C++ 拷贝构造函数的构建,这里做一下笔记,供以后查阅。

我们知道有三种情况类的对象调用拷贝构造函数

1,用一个对象对另外一个对象初始化。2,当该对象作为参数以值传入的方式传给某个函数时候。3,当函数返回一个对象(副本)的时候。 

拷贝构造函数有以下两个定义方式:

X::X(const X& x);
X::X(const X& x, int = 0);// 可以是多参数,但是其第二个参数及其后继参数以一个默认值供应之

如果class没有提供一个显示的拷贝构造函数的时候,又会发生什么?很多人可能会说c++编译器会自动合成一个默认的拷贝构造函数。但是这句话是不对的,只有当编译器认为有必要的时候,才会合成默认拷贝构造函数,那么什么时候编译器认为有必要合成呢?所谓必要,就是当该类不展现bitwise copy semantics(位逐次拷贝)。书中提到有下面四种情况。

1,当class内含一个对象成员,而该对象成员的class声明中有一个拷贝构造函数(不管这个拷贝构造函数怎么生出来的)。

2,当class继承自一个基类,而该基类存在一个拷贝构造函数。

3,当class声明了一个或多个虚函数时。

4,当class派生自一个继承串链,其中有一个或者多个虚基类。

对于情况1和2,既然class中包含的数据成员有拷贝构造函数或者基类有拷贝构造函数,那么也就是说按照bitwise copy semantics方法可能无法胜任,编译器就会合成默认拷贝构造函数。难点在于对3 和 4 的理解。

关于3,如果两个类型相同,则bitwise copy semantics完全可以胜任,但是如果让继承类去初始化基类,就会出现错误。因为有虚指针(vptr).

class Base {
    public:
        Base():value_base(10) {}
        virtual ~Base() {}
        virtual void foo() {cout << " Base::foo() " << endl;}
        virtual void bar() {cout << " Base::bar() " << endl;}
    private:
        int value_base;
};

class Derive: public Base {
    public:
        Derive() : Base(), value_derive(100) {} 
        virtual ~Derive() {}
        virtual void foo1() {cout << "Derive::foo1()" << endl;}
    private:
        int value_derive;
}
Derive d;
Base b(d); //这个过程就会将d切割掉一部分,但是d的vptr指向的是derive类的虚函数表,而b内部的vptr的值显然不能和d的vptr相同,所以这个时候,位逐次拷贝将无能为力,只能祭出拷贝构造函数了。使b的vptr指向Base的虚函数表。
对于4的理解:

每一个编译器对虚拟继承的支持承诺,都表示必须让继承类对象的虚基类子对象位置在执行期间就准备妥当。bitwise copy semantics可能会破坏这个位置,因为bitwise copy semantics同样处理不了继承类对象初始化基类对象,编译器在用继承类对象初始化基类时候,必须合成拷贝构造函数,来设定虚基类指针或者偏移的初值。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值