赋值运算符重载函数 引用返回 与 对象返回

Posted 4nc414g0n

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了赋值运算符重载函数 引用返回 与 对象返回相关的知识,希望对你有一定的参考价值。

引用返回 与 对象返回

代码

正确代码如下(为了验证,我们自己加上了自定义析构函数和拷贝构造函数)

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
class Date
{
public:
	Date(int year = 0, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	Date& operator=(const Date& d)
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
		return *this;
	}
	Date(const Date& d)//拷贝构造函数
	{
		cout << "这是拷贝构造函数" << endl;
	}
	~Date()//析构函数
	{
		cout << "默认析构" << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1(2021, 10, 11);
	Date d2(2021, 11, 2);
	Date d3(2020, 12, 2);
	d1 = d2 = d2;
	return 0;
}

对象返回

传对象返回时回进行如下操作:

  1. 释放对象原来的堆资源
  2. 重新申请堆空间
  3. 拷贝源的值到对象的堆空间的值
  4. 创建临时对象,调用临时对象拷贝构造函数,将临时对象返回
  5. 临时对象结束,调用临时对象析构函数,释放临时对象堆内存
Date operator=(const Date d)
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
		return *this;
	}

如图最后三个析构函数是三个对象生命周期结束时调用的,而上面的三次拷贝构造和析构是因为传对象返回造成的
注意:
在这里可能看不到传对象返回的危害,但是当对于栈这种在堆上开辟空间的类来说会有两次释放同一空间的危害,报错

引用返回

传引用返回:

  1. 释放对象原来的堆资源
  2. 重新申请堆空间
  3. 拷贝源的值到对象的堆空间的值
  4. 返回源对象的引用
Date& operator=(const Date& d)
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
		return *this;
	}


只有三次正常的析构函数调用


总结

如果赋值运算符返回的是对象引用,那么其不会调用类的拷贝构造函数,这是返回对象和返回引用的主要区别,返回引用的效率明显较高


更深入探讨请移步C++本质:类的赋值运算符=的重载,以及深拷贝和浅拷贝

以上是关于赋值运算符重载函数 引用返回 与 对象返回的主要内容,如果未能解决你的问题,请参考以下文章

赋值函数(运算符重载)

赋值运算符重载:返回 void 与返回引用参数

c++重载赋值操作符的返回值是啥?

c++中重载输出操作符,为啥要返回引用

返回对象和返回引用

为啥我们在赋值运算符重载中使用引用返回而不是在加减运算中?