C++(四十二)之赋值运算符重载

在我们的使用类对象的时候,

有时候会直接用赋值运算符来对类的对象直接拷贝!

如果我们没有对赋值运算符做重载的话,

有些编译器是只做浅拷贝,

前面我们有说过浅拷贝的缺点,

请参考: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;  /*返回当前的对象*/
//	} 

结果如下:

 

如果没有做深拷贝的话,有些编译器会直接崩掉。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值