12.5.4 赋值运算符重载

12.5.4 赋值运算符重载

我们再创建一个类对象后,有时会有这样的操作。

	Person p1("张三", 18);
	person p2;
	p2 = p1;

注意看第三行代码,使用了赋值运算符,按理说没有重载前赋值运算符应该不能操作自定义数据类型。
这是因为在一个类定义完成后,编译器会至少生成四种函数:

  • 默认构造函数
  • 默认析构函数
  • 默认拷贝构造函数
  • 赋值运算符重载函数

但是使用默认拷贝构造函数和默认赋值运算符重载函数时要注意,编译器自动生成的都是浅拷贝。如果有属性是定义在堆区的指针,就要避免入坑。
我们可以手动重载赋值运算符,将浅拷贝变为深拷贝。


1、首先我们创建一个Person类,为了简单,只定义一个m_Age属性

class person
{
public:
	int *m_Age;
};

2、再在类中加上构造函数
由于年龄属性是一个指针变量,构造函数应用new关键字在堆区返回一个指针。

	person(int age)
	{
		this->age = new int(age);
	}

3、堆区的数据应由程序员手动开辟和释放,所以要加上析构函数释放属性占用的堆区空间。

	~person()
	{
		if (this->age != NULL)
		{
			delete age;
			age = NULL;
		}
	}

4、对于堆区的数据,如果使用浅拷贝,会出现释放内存出错的bug,这里之前介绍深浅拷贝时已经详细解释过。所以我们要重载拷贝构造函数和赋值运算符。为了方便,本节只重载赋值运算符。
类中添加这样的函数:

	person& operator=(person &p)
	{
		//编译器提供的赋值运算符重载,是浅拷贝
		//this->age = p.age;

		//深拷贝
		//首先要先将本来的指针指向的内存释放干净,再指向新的内存
		if (this->age != NULL)
		{
			delete age;
			age = NULL;
		}
		this->age = new int(*p.age);
		return *this;
	}
  • 这里返回Person&是为了实现连等的使用。如p1=p2=p3;
    完成上面的工作之后,我们就完成了赋值运算符的重载,并且是深拷贝。
    用一个示例区验证以下代码:
void test1()
{
	person p1(10);
	person p2(20);
	person p3(30);

	p3 = p2 = p1;
	cout << *p1.m_Age << endl;
	cout << *p2.m_Age << endl;
	cout << *p3.m_Age << endl;
}

int main()
{
	test1();
	system("pause");
	return 0;
}

运行结果正常,且没有出现内存释放出错的问题:
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值