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中,











评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值