Copy Constructor解惑

本文详细介绍了拷贝构造函数的概念及使用场景,并解释了按位拷贝语义及其潜在问题,帮助读者理解如何正确实现拷贝构造函数。

一   Copy Constructor的定义:

拷贝构造函数的第一个参数与调用的class object 类型相同,可以有多个形参,但是后面的参数都需要提供默认值。

例如:

X::X(const  X& x);

Y::Y(const Y&y,int temp=0);

在大部分情况下,当一个class object以另一个同类实体作为初值时,上述的constructor会被调用。

二   Copy Constructor的三种调用情况:

有三种情况会自动调用Copy Constructor,以一个object的内容作为另外一个class object 的初值。分别是:


1.当对一个object做明确的初始化操作,例如

class X{...};
X x;

X xx=x;//明确地以一个object的内容为另一个class object的初值

2.当object被当做参数交给某个函数时,例如:

extern void foo(X X);
void bar()
{
X xx;
foo(xx);//以xx作为foo()第一个参数的初值
} 

3.当函数传回一个class object时,例如:


X foo_bar(){

X xx;

return xx;

}

二 Copy Constructor 的合成

1.Bitwise Copy Semantics

当我们定义一个类如下所示:

class Word{
public:
Word(const char *);
~Word(){delete [] str;}
private :
int cnt;
char *str;
}
此时,
如果我们定义变量:

情况一:
Word noun("book");
void foo()
{
Word verb=noun;
}
情况二:
Word noun("book");
void foo(Word tempword){//foo定义,此时会产生一个Word类型的临时变量,在临时变量被销毁的时候,str指向的空间也会被释放掉
}
foo(noun);//foo调用

此时,虽然Word没有定义copy constructor,但是编译器也不会合成一个。此时编译器使用Bitwise Copy Semantics(按位拷贝语义)直接将noun对象空间中的类容拷贝到verb对象空间。使用Bitwise Copy Semantics后的对象空间布局如下图所示:


注意在verb对象消亡的时候,str指向的空间也被释放掉了,当noun对象再去访问的时候,str已经是一个野指针,访问不合法,这一点在写程序的时候一定要注意,想当初,我调这个bug调了不知道多久。

2. 不要Bitwise Copy Semantics

 什么时候一个class不展现出"bitewise copy semantics" 呢?有四种情况:

1.当class内含一个member object 而后者的class声明有一个copy constructor时(不论是被class 设计者明确地声明,或者是被编译器合成)。

2.当class继承自一个base class 而后者存在有一个copy constructor时(再次强调,不论是被明确声明或者是被合成而得)。

3.当class声明了一个或者多个virtual functions 时。

4.当class 派生自一个继承串链,其中有一个或多个virtual base classes时。

  前两种情况,编译器必须将member或者base class的"copy constructor调用操作"安插到被合成的copy constructor中,











                
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值