首先我们了解什么是拷贝构造函数和拷贝赋值运算符
拷贝构造函数:
如果一个构造函数的第一个参数时自身类类型的引用,且任何额外参数都有默认值,则此构造函数是拷贝构造函数。
class Test
{
public:
Test(); //默认构造函数
Test(const Test&); //拷贝构造函数
//........
};
此处必须为引用的原因:
如果此处为值传递,则想要进行拷贝的步骤,则首先需要将实参传递到形参,而此过程中就是实参拷贝到形参;则实参到形参就又需要调用拷贝构造函数,然后后面无限调用拷贝构造函数;
eg:
//假设上面拷贝构造函数变为:Test(const Test x);
//则Test a(b);
//将首先需要将实参b拷贝给形参x,就相当于进行了x(b);
//则下一步又需要进行实参b赋值给形参x1;x1(b);
//下面就会进行无限循环
拷贝赋值运算符:
拷贝赋值运算符类似于重载=运算符,但是返回一个指向左侧运算对象的引用。
A& operator=(const A&aa);
有指针时如何使用拷贝函数
当有指针时,不能简单的使用拷贝函数,而应该自己定义出函数体内的内容,针对指针对象需要自己单独开辟出新的空间;
例如:A a(10),b; b(a); 如果此时传入的形参10是一个指针对象,则当a被析构之后,b就会发生错误。
eg:
注意这两行代码针对指针变量的赋值方法:
class A(const A &aa){ a = aa.a; b = new int(*aa.b); } //拷贝构造函数
A& operator=(const A&aa) { a = aa.a; b = new int(*aa.b); return *this; }; //拷贝赋值运算符
#include<iostream>
using namespace std;
class A
{
public:
A(int x,int y) :a(x){ b = new int(y); }
class A(const A &aa){ a = aa.a; b = new int(*aa.b); } //拷贝构造函数
A& operator=(const A&aa) { a = aa.a; b = new int(*aa.b); return *this; }; //拷贝赋值运算符
void print()
{
cout << a << " " << *b << endl;
}
~A(){ delete b; }
private:
int a;
int *b;
};
int main()
{
A a(10,20);
A b(30,40);
b = a; //调用拷贝赋值运算符
A c = a; //这个地方不是赋值,应该是初始化,调用拷贝构造函数
a.~A();
b.print();
c.print();
system("pause");
return 0;
}