C++赋值运算符重载

C++赋值运算符重载

赋值运算符重载和拷贝构造函数的作用类似,都是将类对象进行复制。
需要注意的点也是一样,就是堆区重复释放问题
这个问题的诱因就是,编译器默认的拷贝是浅拷贝,而浅拷贝会出现重复释放内存的现象。
具体可以参考 C++深拷贝与浅拷贝

赋值运算符重载的目的就是复制类,而每个类的内容不尽相同
所以,赋值运算符重载应该定义在类内部

  1. 赋值运算符重载(浅拷贝)

编译器提供的代码是浅拷贝。
此时不能自己定义析构函数,否则会带来堆区重复释放的问题。

#include <iostream>
using namespace std;
#include <string>
class Person
{
    
    
public:

	Person(int age)
	{
    
    
		//将年龄数据开辟到堆区
		m_Age = new int(age);
	}

	//重载赋值运算符 
	//安利一个tip
	//在不知道返回值类型的时候可以用void代替,
	//等到定义完毕后再修改返回值类型即可
	void operator=(Person &p)
	{
    
    
		if (m_Age != NULL)
		{
    
    
			delete m_Age;
			m_Age = NULL;
		}
		//编译器提供的代码是浅拷贝
		m_Age = p.m_Age;

	}
	//此时不能自己定义析构函数,否则会带来堆区重复释放的问题
	//~Person()
	//{
    
    
	//	if (m_Age != NULL)
	//	{
    
    
	//		delete m_Age;
	//		m_Age = NULL;
	//	}
	//}

	//年龄的指针
	int *m_Age;
};


void test01()
{
    
    
	Person p1(18);

	Person p2(20);

	Person p3(30);

	p2 = p1; //赋值操作

	cout << "p1的年龄为:" << *p1.m_Age << endl;

	cout << "p2的年龄为:" << *p2.m_Age << endl;

	cout << "p3的年龄为:" << *p3.m_Age << endl;
}

int main() {
    
    

	test01();

	system("pause");

	return 0;
}
  1. 赋值运算符重载(深拷贝)

提供深拷贝 解决浅拷贝堆区重复释放的问题

#include <iostream>
using namespace std;
#include <string>
class Person
{
    
    
public:

	Person(int age)
	{
    
    
		//将年龄数据开辟到堆区
		m_Age = new int(age);
	}

	//重载赋值运算符 
	void operator=(Person &p)
	{
    
    
		if (m_Age != NULL)
		{
    
    
			delete m_Age;
			m_Age = NULL;
		}
		编译器提供的代码是浅拷贝
		//m_Age = p.m_Age;

		//提供深拷贝 解决浅拷贝的问题
		m_Age = new int(*p.m_Age);

	}

	~Person()
	{
    
    
		if (m_Age != NULL)
		{
    
    
			delete m_Age;
			m_Age = NULL;
		}
	}

	//年龄的指针
	int *m_Age;

};


void test01()
{
    
    
	Person p1(18);

	Person p2(20);

	Person p3(30);

	p2 = p1; //赋值操作

	cout << "p1的年龄为:" << *p1.m_Age << endl;

	cout << "p2的年龄为:" << *p2.m_Age << endl;

	cout << "p3的年龄为:" << *p3.m_Age << endl;
}

int main() {
    
    

	test01();

	system("pause");

	return 0;
}
  1. 解决连续赋值问题

曾记否,我们原来的赋值运算有这样连续赋值的形式

	int a = 10;
	int b = 20;
	int c = 30;
	c = b = a;
  • 大家可以用上面的程序试一试
    结果可想而知,必然是跑不通的。
    如何解决呢?
  • 由于我们一开始定义的是void返回值,都知道void是无法再次赋值的!
    那么就应该将返回值类型修改为Person类
    等等,你确定是Person类?不是Person&?
  • 好吧,应该是Person&,为什么呐?
    因为如果是Person类,返回的将是一个局部变量,而局部变量在函数运行结束之后就销毁了!
    这是报错的图片
    这是正确的代码
#include <iostream>
using namespace std;
#include <string>
class Person
{
    
    
public:

	Person(int age)
	{
    
    
		//将年龄数据开辟到堆区
		m_Age = new int(age);
	}

	//重载赋值运算符 
	Person& operator=(Person &p)
	{
    
    
		if (m_Age != NULL)
		{
    
    
			delete m_Age;
			m_Age = NULL;
		}
		编译器提供的代码是浅拷贝
		//m_Age = p.m_Age;

		//提供深拷贝 解决浅拷贝的问题
		m_Age = new int(*p.m_Age);

		//返回自身
		return *this;
	}
	~Person()
	{
    
    
		if (m_Age != NULL)
		{
    
    
			delete m_Age;
			m_Age = NULL;
		}
	}

	//年龄的指针
	int *m_Age;

};


void test01()
{
    
    
	Person p1(18);

	Person p2(20);

	Person p3(30);

	p3 = p2 = p1; //赋值操作

	cout << "p1的年龄为:" << *p1.m_Age << endl;

	cout << "p2的年龄为:" << *p2.m_Age << endl;

	cout << "p3的年龄为:" << *p3.m_Age << endl;
}

int main() {
    
    

	test01();
	
	system("pause");

	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_48622537/article/details/110287860