程序员社区

赋值运算符重载

赋值运算符重载

c++默认提供的四种函数:默认构造,析构,拷贝构造(值拷贝),operator=(值拷贝)

深浅拷贝的问题一般出现在类中有属性是要开辟在堆区的,并且析构函数中写了释放堆区内存的代码,那么要注意不要对堆区内存进行重复释放的操作

1.深浅拷贝的问题
operator=编译器提供的浅拷贝操作

//赋值运算符重载(赋值拷贝)
	wood& operator=(wood& w1) //w1是要进行拷贝的值
	{
		//浅拷贝
		num = w.num;
	}

自己改写为深拷贝的操作
注意:如果是深拷贝赋值,那么在赋值拷贝之前,被赋值的对象可能已经在堆区开辟了内存,所以要先释放在堆区开辟的内存

#include<iostream>
using namespace std;
class wood {
public:
	wood(int num) {
		this->num = new int(num);
		cout << "构造函数调用" << endl;
	}
	//赋值运算符重载(赋值拷贝)
	wood& operator=(wood& w1) //w1是要进行拷贝的值
	{
		//浅拷贝
		//num = w.num;
		//深拷贝
		//防止自赋值
		if (this != &w1)
		{
			//如果本身已经在堆区开辟内存,就先释放
			if (num != NULL)
			{
				delete num;
				num = NULL;
			}
			num = new int(*w1.num);
			return *this;
		}
	}
	//析构函数
	~wood() {
		if (num != NULL)
		{
			delete num;
			num = NULL;
		}
		cout << "析构函数调用" << endl;
	}
	int* num;
};
void test()
{
	wood w(10);
	cout << *w.num << endl;
	wood w1(20);
	w1 = w;
	cout << *w1.num << endl;  //在析构函数里面写了delete语句释放内存后,就会造成内存的重复释放,需要进行深拷贝操作
}

int main()
{
	test();
	return 0;
}

默认拷贝构造(浅拷贝)

在这里插入图片描述
在这里插入图片描述

改造为深拷贝

进行深拷贝的时候,不需要判断被赋值的对象是否在堆区开辟了内存,因为这里相当于进行新创建对象的初始化操作,新对象还没有进行任何属性初始化操作,除非无参构造里面对新对象做了属性堆区开辟的操作
在这里插入图片描述

#include<iostream>
using namespace std;
class wood {
public:
	wood(int num) {
		this->num = new int(num);
		cout << "构造函数调用" << endl;
	}
	wood(wood & w)
	{
		this->num = new int(*w.num);
	}
	//析构函数
	~wood() {
		if (num != NULL)
		{
			delete num;
			num = NULL;
		}
		cout << "析构函数调用" << endl;
	}
private:
	int* num;
};
void test()
{
	wood w1(10);
	wood w = w1;//默认拷贝构造
}
int main()
{
	test();
	return 0;
}

在这里插入图片描述

注意:值拷贝过程中堆区内存被重复释放的问题
可用传引用的方式解决

#include<iostream>
using namespace std;
class wood {
	friend ostream& operator<<(ostream& cout, wood wood);
public:
	wood(int num) {
		this->num = new int(num);
		cout << "构造函数调用" << endl;
	}
	
	//析构函数
	~wood() {
		if (num != NULL)
		{
			delete num;
			num = NULL;
		}
		cout << "析构函数调用" << endl;
	}
private:
	int* num;
};
//这里是值拷贝
ostream& operator<<(ostream& cout, wood wood)
{
	cout << "木头的数量为:" << *wood.num << endl;
	return cout;
}
void test()
{
	wood w(10);
	cout << w << endl;
	//operator<<(cout, w);
	
}
int main()
{
	test();
	return 0;
}

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

赞(0) 打赏
未经允许不得转载:IDEA激活码 » 赋值运算符重载

相关推荐

  • 暂无文章

一个分享Java & Python知识的社区