一、 什么是拷贝构造函数
就是构造函数的一种,用于实现同一类对象的构建和初始化。
拷贝构造函数是由普通构造函数和赋值操作符共同实现的。
一般用于:
(1) 函数形参,值传递
(2) 函数返回值,值传递
(3) 一个对象给另一个对象初始化
如:Test a3=Test(a1);
因为值传递是传递对象的副本,所以会编译器会自动调用拷贝构造函数。
用一个已存在的对象对一个新的对象初始化,不会生成临时对象,而是新对象直接调用已存在对象的拷贝构造函数。
二、 如何重载赋值操作符
Test&operator=(const Test &a)
{
this->data=a.data;
return *this;
}
三、 上述两者的纠结关系
先来看看如下的程序,实现了重载赋值操作符和拷贝构造函数:
#include <iostream>
using namespace std;
class Test
{
private :
int data;
public :
Test(){}
Test(int n):data(n){}
Test(const Test &old)
{
*this=old;
cout<<"拷贝构造函数!"<<endl;
}
Test &operator=(const Test &a)
{
this->data=a.data;
cout<<"赋值运算符重载啦"<<endl;
return *this;
}
};
int main()
{
Test a1(5);
Test a2;
a2=a1;
Test a3=Test(a1);
return 0;
}
这就是被调用的重载赋值操作符函数:
其中:
如果红框中不加 & 引用标识符,那么函数返回值属于值传递,编译器调用拷贝构造函数生成一个对象副本。
如果红框中不加 & 引用标识符,那么函数参数值属于值传递,编译器调用拷贝构造函数生成一个对象副本。
这就是被调用的拷贝构造函数:
调用了赋值操作符函数。
所以如果赋值操作符函数不是const & Test 引用类型,而是值传递,就会有:
赋值运算符的参数值传递调用拷贝构造函数
拷贝构造函数中的“=”调用赋值运算符函数
赋值运算符的参数值传递调用拷贝构造函数
拷贝构造函数中的“=”调用赋值运算符函数
。
。
。
重复调用直至栈溢出。
总结:
(1) 拷贝构造函数的返回值和传入的参数一定要是引用类型(否则栈溢出),而且一般都是不希望参数在函数中被改变,所以是const 常引用。
(2) 拷贝构造函数用于,生成对象副本(值传递就会生成对象副本)和给新对象初始化时(新对象调用旧对象的拷贝构造函数)。