关于复制构造函数(拷贝构造函数)和赋值操作符(拷贝赋值函数)应该知道的

来源:互联网 发布:拍拍贷网络借贷平台 编辑:程序博客网 时间:2024/04/29 00:11

每个类只有一个析构函数,但可以有多个构造函数(包含一个拷贝构造函数,其他的为普通构造函数)和多个赋值函数(包含一个拷贝构造函数,其他的为普通构造函数)。一般的,对于任何一个类A,如果程序员不显示地声明和定义上述函数,c++编译器将自动为A产生4个public inline的默认函数。

 

默认的拷贝构造函数和默认的赋值构造函数均采用“按成员拷贝”默认方式来实现。但是,基本类型变量(包括指针)的拷贝和赋值时按bit进行的,因此加入类中含有指针成员,这两个默认函数的执行结果将是两个对象中的对应指针成员指向相同的对象,而这在一般情况下并非我们所期望的。

 

拷贝构造函数应注意的问题:

 

为什么不允许定义这种形式 A(A copy) 的拷贝构造函数?

 

这个拷贝构造函数在参数传递的过程中又要调用拷贝构造函数本身,而调用拷贝构造函数时又要先进行参数传递,参数传递又要调用拷贝构造函数。。。。。。于是陷入不停的分配堆栈的无限递归中,而每次压栈过程中又嵌套了压栈,致使每一次的压栈都不能完成,因此,编译器通过不了这种形式的拷贝构造函数。

 

如果不主动编写拷贝构造函数和拷贝赋值函数,编译器将以“按成员拷贝”的方式自动生成相应的默认函数。倘若类中含有指针成员或引用成员,那么这两个默认的函数就可能隐含错误。

 

以类String的两个对象a、b为例。假设a.m_data的内容为“Hello”,b.m_data的内容为“world”。现将a赋值给b,默认赋值函数的“按成员拷贝”意味着执行b.m_data=a.m_data。这将造成三个错误:

(1)b.m_data原持有的内存没有被释放,造成内存泄漏。

(2)b.m_data和a.m_data指向同一块内存区域,a或b任何一方变动都会影响另一方

(3)在对象被析构时,m_data被delete了两次。



拷贝构造函数和拷贝赋值函数非常容易混淆,常导致错写、错用。拷贝构造函数是在对象被创建并用另一个已经存在的对象来初始化它时调用的;

而赋值函数只能把一个对象赋值给另一个已经存在的对象,使得那个已经存在的对象具有和源对象相同的状态。

 

String a(“hello”);

Sting b(“world”);

Sting c=a;(或String c=a;) //调用的都是拷贝构造函数

c=b;                  //调用的是赋值函数

原创粉丝点击