C++ 赋值运算符重载

 个人主页:Jason_from_China-CSDN博客

所属栏目:C++系统性学习_Jason_from_China的博客-CSDN博客

所属栏目:C++知识点的补充_Jason_from_China的博客-CSDN博客

概念概述

赋值运算符重载的特点:

  1. 成员函数:赋值运算符重载必须定义为类的成员函数。
  2. 参数:建议将参数声明为const类型的类引用,以避免不必要的拷贝。
  3. 返回值:应有返回值,且建议为当前类类型的引用,这样可以支持连续赋值操作,并提高效率。

编译器自动生成的赋值运算符:

  • 如果没有显式实现赋值运算符重载,编译器会提供一个默认实现。
  • 默认赋值运算符对内置类型成员变量执行值拷贝或浅拷贝。
  • 对自定义类型成员变量,会调用其赋值运算符重载函数。

特定情况下的赋值运算符重载:

  • 对于像Date这样只有内置类型成员的类,编译器自动生成的赋值运算符通常足够使用。
  • 对于像Stack这样包含指向资源的成员的类,需要自定义赋值运算符以实现深拷贝。
  • 对于像MyQueue这样包含自定义类型成员的类,如果这些成员的赋值运算符已经正确实现,通常不需要为MyQueue显式实现赋值运算符重载。

额外技巧:

  • 如果一个类显式实现了析构函数并释放资源,通常也需要显式实现赋值运算符重载,以确保资源被正确管理。

赋值运算符重载的使用以及注意事项

1,有返回值,建议写成const类类型的引用。因为C++规定类类型的传值传参,会调用拷贝构造,传递引用会减少拷贝(提高效率)

2,连续赋值的返回值

d3=d1;

返回值是d3,所以我们写代码的时候,要注意返回值,很可能是this

第一次赋值

第二次赋值

3,当返回的节点是d2,如何实现返回d2(用this,this本身指向的就是返回值)(这里注意:有返回值就支持连续赋值,但是返回的时候,需要注意)

注意:这里返回是可以用引用返回的,因为赋值运算符重载是两个已有的对象。出去作用域是依旧存在的(这里代码是传值返回,会增加拷贝)

4,这里还有一个问题,就是d1可以复制給給d1,所以为了防止自己給自己赋值 ,会进行判断

代码实现

//.h文件
//运算符重载,比较大小的实现,不在类里面实现
class Date
{
public:
	Date(int year = 1000, int month = 1, int day = 1);//声明给,定义不给
	Date(Date& d);
	void print();

	bool operator<(const Date& d);

	//比较日期大小(重载为成员函数)
	Date& operator++();
	Date& operator++(int);

	//赋值运算符重载(这里是可以加上const的,因为这里改变的是this不是d)
	Date& operator=(const Date& d);

private:
	int _year;
	int _month;
	int _day;
};


//.cpp实现文件
#include"类和对象的通篇实现.h"
//构造函数的实现(全缺省构造函数的实现)
Date::Date(int year, int month, int day)
{
	_year = year;
	_month = month;
	_day = day;
}
//拷贝构造的实现
Date::Date(Date& d)
{
	_year = d._year;
	_month = d._month;
	_day = d._day;
}
//打印函数的实现
void Date::print()
{
	cout << _year << "/" << _month << "/" << _day << endl;
}

//日期类的比较日期的大小,this-> < d.year 此时返回
bool Date::operator<(const Date& d)
{
	//比较年
	if (this->_year < d._year)
	{
		return true;
	}
	else
	{
		if (this->_year == d._year && this->_month < d._month)//比较月
		{
			return true;
		}
		else if (this->_year == d._year && this->_month < d._month && this->_day < d._day)//比较日
		{
			return true;
		}
	}
	return false;
}

//前置++
Date& Date::operator++()
{
	this->_day += 1;
	return *this;
}
//后置++
Date& Date::operator++(int)
{
	Date tmp = *this;
	this->_day += 1;
	return tmp;
}

//赋值运算符重载(这里是可以加上const的,因为这里改变的是this不是d)
Date& Date::operator=(const Date& d)
{
	//地址不一样才进行赋值
	if (this != &d)
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}
	return *this;
}





//.cpp测试文件
//运算符重载,比较大小
int main()
{
	//构造和拷贝构造函数的使用
	Date d1(1000, 2, 1);
	d1.print();
	Date d2 = d1;
	d2.print();

	//比较年月日
	Date d3(999, 1, 1);
	bool ret1 = d1.operator<(d3);
	cout << ret1 << endl;

	Date d4(1100, 1, 1);
	bool ret2 = d1.operator<(d4);
	cout << ret2 << endl;

	//前置++和后置++
	cout << "前置++和后置++" << endl;
	d4.print();//1100 ,1,1
	
	d4.operator++();
	d4.print();

	Date ret = d4.operator++(1);
	ret.print();
	d4.print();


	//赋值运算符重载 
	cout << "赋值运算符重载" << endl;
	Date d5(1, 1, 1);
	d5.print();
	d5 = d4;//这样写也是对的
	//d5.operator=(d4);//这样写也是对的
	d5.print();
	 
	return 0;
}

赋值运算符重载什么时候需要自己实现

注意:默认的赋值运算符重载也会完成浅拷贝(有资源,就需要自己完成赋值运算符重载)

1,内置类型不指向什么资源,不需要自己实现,编译器自动生成的就可以实现

2,栈和深拷贝,都需要自己写,和拷贝构造非常相似

3,如果写了析构函数,那么赋值运算符重载就需要自己写

几个函数之间进行对比

1、构造一般都需要自己写,自己传参定义初始化

2、析构,构造时有资源申请(如malloc或者fopen)等,就需要显示写析构函数

3、拷贝构造和赋值重载,显示写了析构,内部管理资源,就需要显示实现深拷贝

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值