深度搜索C++对象模型 - 复制构造函数



深度搜索C++对象模型: 复制构造函数

由构造函数篇可以猜到, 复制构造函数其实也"不一定"会被编译器产生..

提到复制,自然是类成员之间的复制, 有三种情况 会把一个 class object 的内容作为另一个 class object 的初值:
--> 对一个 class object 做显示的初始化操作:
class A { };
A a;
A b = a;

--> 对一个 class object 做传值调用:
void Func( A a );
A a;
void Func( a );

--> 当函数传递回一个 class object :
A Func()
{
 A a;
 return a;
}

//*********************************************************************************************//

当一个 class object "不展现" Bitwise Copy Semantics ( 位逐次拷贝 ) 时, 编译器才会为 class 合成一个复制构造函数;
对于一个普通的类来说 他本身是"展现位逐次拷贝" 的,但是在以下几种情况 他会"失去位逐次拷贝",此时编译器会为他合成复制构造函数

//-----------------------------------------------------------------------------------------------------------------------//

---> 当 class 内含一个 class member object, 而且这个 class member object 有一个 复制构造函数,
( "重申": 存在一个复制构造函数, 不管这个复制构造函数是被显示了声明了,还是因为某种原因被编译器合成了 )

//-----------------------------------------------------------------------------------------------------------------------//

---> 当 class 继承自一个 base class, 而且这个 base class 存在一个 复制构造函数,
( "重申": 存在一个复制构造函数, 不管这个复制构造函数是被显示了声明了,还是因为某种原因被编译器合成了 )

//-----------------------------------------------------------------------------------------------------------------------//

---> 当 class 内使用了 virtual Function 机制: ( 主要是 vptr )
class ZooAnimal { public: virtual ZooAnimal(); };
class Bear : public ZooAnimal { };

Bear yogi;
Bear wninie = yogi;
此时 yogi 会被 默认构造函数初始化, 然后 yogi 的 vptr 被设定为指向了 Bear class virtual table,
因此 把 yogi 的 vptr 通过 "位逐次拷贝" 复制给 wninie 是安全的;

ZooAnimal franny = yogi;
此时 发生了一次"切割", 但是我们通过 "位逐次拷贝" 分析,则会发现 franny 的 vptr 被设置为了 yogi 的 vptr ( 其实是 Bear class virtual table )
这不符合实际情况, 所以编译器要合成一个默认复制构造函数, 来显示的把 franny 的 vptr 设置为指向 ZooAnimal class virtual table;

//-----------------------------------------------------------------------------------------------------------------------//

---> 当 class 派生自一个继承串链, 其中有 virtual base class
class A { };
class B : virtual public A { };

//-----------------------------------------------------------------------------------------------------------------------//

总结: 以上4种情况, "编译器必须为未声明复制构造函数的类合成一个默认复制构造函数",

至于"不属于以上4种情况的而且又没有声明复制构造函数", "没有复制构造函数会被合成出来";

什么时候我们需要一个 复制构造函数?
答案: 不一定
一般来说 我们没有任何理由提供给程序一个复制构造函数,因为编译器已经为我们做了最合理的事情
但是 当我们预见到我们的程序需要进行" 传值复制一个 member object " 的时候 那么提供一个复制构造函数是合情合理的

//*********************************************************************************************//

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值