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


    类的默认函数

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

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

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

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

    重载赋值运算符

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

    相关注意事项

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


    在这里插入图片描述

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 注意在赋值运算符重载函数中,先判断是否在堆区有内存,有的话先释放,再重新开辟。
  • 相关阅读:
    Windows下tomcat与idea控制台乱码问题
    DDL语句
    深入理解MySQL索引:从原理到最佳实践
    Servlet 请求和响应
    软件测试/测试开发/人工智能丨Python类型转换
    Unity 2D入门项目:Ruby‘s Adventure(三)Unity调色板工具栏的介绍
    SSM学习——bean实例化(2)
    CAS号:1937270-46-6|PC Biotin-PEG3-azide|PC生物素-PEG3-叠氮化物
    C++初阶(封装+多态--整理的自认为很详细)
    【OpenCV-Python】教程:3-15 分水岭图像分割
  • 原文地址:https://blog.csdn.net/weixin_48668114/article/details/132925157