标签:
C++类的设计中,如果某些函数没有显式定义,C++会自动生成,复制构造函数便是其中之一,其他的还有默认构造函数、赋值操作符、默认析构函数、地址操作符。一个类的复制构造函数的原型一般为: Class_name (const Class_name &);
一、何时调用复制构造函数
在新建一个对象并将其初始化为同类对象的时候,常常会调用复制构造函数,如:
Class_name A(B);
Class_name A = B ;
Class_name A = Class_name(B);
Class_name *p = new Class_name(A);// 用A初始化一个匿名对象,并将其地址赋予指针P
每当程序生成对象副本时,编译器都会调用复制构造函数。具体地说,当函数按值传递对象或生成临时对象时,编译器都会调用复制构造函数。如当3个Vector对象相加时,编译器会调用复制构造函数来生成临时对象。
二、复制构造函数的浅复制
默认的复制构造函数是浅复制,即逐个复制非静态成员数据的值。
(1)如果类成员是另一个类的对象,那么将调用另一个对象的复制构造函数;
(2)静态成员数据不被复制,因为它们属于整个类,而不是一个对象。
(3)如果成员中含有含有指针P,那么它的地址也会赋给新的对象中相应的P,这样会导致两个或多个变量指向同一个指针——比较危险的一件事。
三、复制构造函数的深复制
显式地定义复制构造函数可以有效解决浅复制的弊端。下面以一个自定义的MyString类作为例子:
假若是使用默认的复制构造函数,则程序很容易崩溃,比如当你创建了对象A,用A初始化B(A和B的str指向同一个地址),然后销毁A(此时A的str指向的内存已被收回),之后你如果想销毁B,则可能使程序崩溃。
解决方法是显式定义复制构造函数:
在函数中使用动态内存分配,在函数里面也可以显性改变静态数据成员的值。与new相对应,在析构函数中使用delete关键字销毁内存:
End.
标签:
原文地址:http://www.cnblogs.com/Vincent-Bryan/p/5304359.html