初始重载操作符时,老师顺便通过重载赋值操作符“=”,讲了深拷贝和浅拷贝的问题。即在类中有引用类型的成员,比如string,指针......如下面代码中的Test类
class Test
{
public:
//引用类型成员
int*a;
//构造函数
Test(int x)
{
a=new int(x);//让a指向x
}
};
如果要拷贝这种类的一个对象,一定要使用深拷贝。因为浅拷贝会导致引用类型成员所指向的地址都和被拷贝对象中的一样。
但是老师给出了如下这种深拷贝的方法:
class Test
{
public:
//引用类型成员
int*a;
//构造函数
Test(int x)
{
a=new int(x);//让a指向x
}
//深拷贝的方法,慎学!
//重载赋值操作符=
Test& operator=(Test& p)
{
a = new int(*p.a);
return *this;
}
};
以上这种方法的原理就是new了一个指向不同地址,但是相同值的a。
如果采用以下这种方式,可以完美地使用以上方法进行深拷贝:
int main()
{
Test test1(1);
Test test2(2);
test2=test1;
}
如果采用以下这种方法,就完美入坑:
int main()
{
Test test1(1);
Test test2=test1;
}
采用下面第二种方法不会深拷贝,即不会调用重载赋值操作符的方法,只会用内置默认的赋值,从而浅拷贝了。
之所以这样,是因为要调用重载的赋值操作符,等号左边必须是Test类型,才会调用重载后的方法。但是第二种方法中“Test test2=test1;”,test2还没有声明时就先使用了等号,系统就使用默认的赋值等号了。
所以,要使用深拷贝,最好还是使用构造函数深拷贝。