C++系列赋值运算符重载

赋值运算符重载

  • 类的默认函数
    • 拷贝构造函数和赋值运算符
  • 重载赋值运算符
    • 相关注意事项

类的默认函数

一个类至少有4个默认函数:

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

拷贝构造函数和赋值运算符

  • 拷贝构造函数是在创建类的时候调用的,之前类并不存在。
  • 赋值运算符是在两个类均存在的情况下,把一个类的属性全部赋值给另外一个类。
  • 默认的拷贝构造函数和默认的赋值运算符在对象有堆区内存时,因为默认的均是浅拷贝,所以均会存在内存重复释放的问题。

重载赋值运算符

  • 语法:类名& operator=(const 类名& ref_h)

相关注意事项

  • 在对象的属性有在堆区开辟内存的情况下,不管是拷贝构造函数还是赋值运算符,都需要进行自定义。
  • 使用new在堆区重新开辟空间,避免重复释放。

  • 浅拷贝
    C++系列赋值运算符重载_第1张图片

  • 深拷贝


C++系列赋值运算符重载_第2张图片

code:
	#include 
	using namespace std;
	class Horse
	{
	private:
		int *m_age;
	public:
		Horse(int ref_age)
		{
			m_age = new int(ref_age);
		}
		Horse(const Horse& ref_h)
		{
			m_age = new int(*ref_h.m_age);
			//m_age = ref_h.m_age;   //默认的构造函数是这种实现方式,简单的赋值操作,在存在指针时,只是将指针简单赋值,指针指向的堆区空间并不进行拷贝。
			cout << "拷贝, " << m_age << ",  " << ref_h.m_age << ", age: " << * ref_h.m_age << endl;
		}
		
		Horse& operator=(const Horse& ref_h)		// 返回自身的引用,链式编程,实现连等操作
		{
			if (this == &ref_h)		// 如果是自身赋值,如h1=h1,直接返回
				cout << "自身赋值" << endl;
				return *this;
			// 如果对象已经有开辟了空间,先进行释放
			if (m_age != NULL)
			{
				delete m_age;
				m_age = NULL;
			}
			//m_age = ref_h.m_age;   //默认的是这种实现方式,简单的赋值操作,在存在指针时,只是将指针简单赋值,指针指向的堆区空间并不进行拷贝。
			m_age = new int(*ref_h.m_age); // 深拷贝
			cout << "=," << m_age << ",  " << ref_h.m_age << ", age: " << * ref_h.m_age << endl;
			return *this;
		}
		
		~Horse()
		{
			if (m_age != NULL)
			{
				cout << "析构:" <<  m_age << endl;
				delete m_age;
				m_age = NULL;
			}
		}
		
		void show_info()
		{
			cout << "age: " << * m_age << endl;
		}
	};
	
	// 对拷贝构造函数的测试
	void test01()
	{
		Horse h1(0);
		h1.show_info();
		Horse h2(h1);
		h2.show_info();
	}
	
	// 对=操作符的测试
	void test02()
	{
		Horse h1(88);
		Horse h2(2);
		Horse h3(5);
		h3 = h2 = h1;
		h1.show_info();
		h2.show_info();
		h3.show_info();
	}
	
	void main()
	{
		test01();
		cout << "************************" << endl;
		test02();
		system("pause");
	}
result:
	age: 0
	拷贝, 0000024C16116510,  0000024C16116A50, age: 0
	age: 0
	析构:0000024C16116510
	析构:0000024C16116A50
	************************
	=,0000024C16116150,  0000024C16116750, age: 88
	=,0000024C161164D0,  0000024C16116150, age: 88
	age: 88
	age: 88
	age: 88
	析构:0000024C161164D0
	析构:0000024C16116150
	析构:0000024C16116750
  • 注意在赋值运算符重载函数中,先判断是否在堆区有内存,有的话先释放,再重新开辟。

你可能感兴趣的:(c++,开发语言)