在我们的使用类对象的时候,
有时候会直接用赋值运算符来对类的对象直接拷贝!
如果我们没有对赋值运算符做重载的话,
有些编译器是只做浅拷贝,
前面我们有说过浅拷贝的缺点,
请参考:https://blog.csdn.net/shao15232/article/details/104540994
所以我们今天要对赋值运算符进行深拷贝的重载。
下面我们举例说明:
/****************************************************
* brief : =运算符重载
* author : shao
* date : 2020-03-10
* note : =运算符,在编译器内部有做重载。
* 比如我们在对对象的直接赋值。
* 这个时候调用的是拷贝构造函数。
* 但是这个时候只是浅拷贝,
* 我们需要对其修改成深拷贝。
*
****************************************************/
#include <iostream>
#include <string>
using namespace std;
class Person1{
public:
int p_age;
int p_ID;
Person1 ()
{
this->p_age = 10;
this->p_ID = 20;
}
Person1(int age, int ID)
{
this->p_age = age;
this->p_ID = ID;
}
};
void test01(void)
{
Person1 p1(5, 7);
Person1 p2 = p1;
cout << "p1.p_age : " << p1.p_age << ", p1.p_ID : " << p1.p_ID << endl;
cout << "p2.p_age : " << p2.p_age << ", p2.p_ID : " << p2.p_ID << endl;
/*到这里我们打印出来信息,看上去没什么问题。
*在对对象的直接赋值中,=的重载看上去也默认实现了。
*/
}
class Person2{
public:
char *name;
Person2(char *name)
{
this->name = new char[strlen(name) + 1]; //先分配空间,用new就不要用malloc了
strcpy(this->name, name);
}
Person2 & operator=(const Person2 &p)
{
cout << "=运算符重载 " << endl;
/*深拷贝的目的是把p的内容拷贝到当前对象身上*/
/*1、如果当前对象有内容,那么先清空*/
if(this->name != NULL)
{
delete [] this->name; /*释放之前已经分配的空间*/
this->name = NULL; /*防止野指针 */
}
/*2、再进行深拷贝*/
this->name= new char[strlen(p.name) + 1];
strcpy(this->name, p.name);
/*
* 注意:在这里为什么要返回当前对象?
* 因为我们使用的形式是 p2 = p1;
* 而我们的操作符是 =,所以返回
* 的需要是调用该赋值操作符的对象,
* 也就是左值自身。所以必须要用引用的方式返回。
* 故return *this;
*/
return *this; /*返回当前的对象*/
}
~Person2()
{
if(this->name != NULL)
{
delete [] this->name; //释放空间
this->name = NULL; //防止野指针
}
}
};
void test02(void)
{
Person2 *p3 = new Person2("狗蛋");
Person2 p4 = *p3;
cout << "p4.name : " << p4.name << endl;
Person2 *p5 = new Person2("老王");
*p5 = *p3;
delete p3;
cout << "p5.name : " << p5->name << endl;
}
int main(void)
{
test01();
test02();
return 0;
}
结果如下:
当我们注销赋值运算符重载函数时,
//Person2 & operator=(const Person2 &p)
// {
// cout << "=运算符重载 " << endl;
//
// /*深拷贝的目的是把p的内容拷贝到当前对象身上*/
// /*1、如果当前对象有内容,那么先清空*/
// if(this->name != NULL)
// {
// delete [] this->name; /*释放之前已经分配的空间*/
// this->name = NULL; /*防止野指针 */
// }
//
// /*2、再进行深拷贝*/
// this->name= new char[strlen(p.name) + 1];
// strcpy(this->name, p.name);
//
//
// /*
// * 注意:在这里为什么要返回当前对象?
// * 因为我们使用的形式是 p2 = p1;
// * 而我们的操作符是 =,所以返回
// * 的需要是调用该赋值操作符的对象,
// * 也就是左值自身。所以必须要用引用的方式返回。
// * 故return *this;
// */
// return *this; /*返回当前的对象*/
// }
结果如下:
如果没有做深拷贝的话,有些编译器会直接崩掉。