C++运算符重载

文章目录

一、运算符重载

1、规定
  • C++允许我们对类类型使用运算符,但要我们自己通过运算符重载完成类类型的运算,如果没有对应的运算符重载就会报错。
  • 运算符重载需要使用特殊关键词operator后跟运算符来完成定义。它跟函数写法一样,具有返回值,函数参数类型,和函数体。
  • 运算符重载不会改变运算符的优先级和结合性。
  • 运算符重载不能重载C++里没有规定的符号,但 .* :: sizeof ?: . 这五个运算符不能重载。

.* 运算符的作用,用于定义类的成员函数指针

cpp 复制代码
//类成员函数指针
#include <iostream>
using namespace std;

class A
{
public:
	void fun()
	{
		cout << "A::fun" << endl;
	}
};

typedef void(A::*PF)();
int main()
{
	void(A::*pf)();
	pf = &A::fun;
	PF p = &A::fun;
	//调用类函数要先创建一个对象
	A a;
	//然后调用函数指针用.*
	(a.*pf)();
	return 0;
}
2、operator关键词的使用

对于类类型的使用运算符编译器是不知道要干嘛的就需要自己写函数,自己实现功能。

就比如日期类的大小比较。


多少天后日期是多少

cpp 复制代码
	//返回每该月有多少天
	int GetMonthDay()
	{
		static int  arr[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
		if (_month == 2 && (_year % 4 == 0 && _year % 100 != 0 || _year%400==0))
		{
			return 29;
		}
		return arr[_month];
	}

	Date operator+=(int day)
	{
		_day += day;
		while (_day > (this->GetMonthDay()))
		{
			_day -= this->GetMonthDay();
			_month++;
			if (_month >= 13)
			{
				_year++;
				_month = 1;
			}
		}
		return *this;
	}

判断日期是否相等

cpp 复制代码
bool operator==(const Date& d)
{
	return (_year == d._year && _month == d._month && _day == d._day);
}
  • 前置operator++ 和 后置operator++

编译器会做特殊处理,后置++会多个int类型的形参

cpp 复制代码
	//前置++
	//出了作用域值还在,用引用返回可以减少拷贝
	Date& operator++()
	{
		_day++;
		if (_day > this->GetMonthDay())
		{
			_day -= this->GetMonthDay();
			_month++;
			if (_month > 12)
			{
				_year++;
				_month = 1;
			}
		}
		return *this;
	}

	//后置++
	Date operator++(int i)
	{
		Date tmp = *this;
		_day++;
		if (_day > this->GetMonthDay())
		{
			_day -= this->GetMonthDay();
			_month++;
			if (_month > 12)
			{
				_year++;
				_month = 1;
			}
		}
		return tmp;
	}

二、赋值运算符的重载

1、功能
  • 对两个已经存在的类的对象进行赋值拷贝操作。

  • 要跟拷贝构造区分,拷贝构造是一个已经存在,给另一个初始化时进行的拷贝操作。

  • 如果不写赋值运算符重载函数,系统会自动生成,但是浅拷贝,一个字节一个字节的拷贝,对于占用资源的还是要自己写才好。

  • 支持连续赋值,所以返回值就是类类型本身。

cpp 复制代码
	//赋值运算符重载
	Date& operator=(const Date& d)
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;

		return *this;
	}

总结如果显示写了析构,就要显示写赋值运算符重载。

2、使用

日期类比较大小

cpp 复制代码
#include <iostream>
#include <stdbool.h>

class Date
{
public:
	Date(int year = 1, int month = 1, int day = 1);

	bool operator <(const Date& d);
	bool operator >(const Date& d);
	bool operator <=(const Date& d);
	bool operator >=(const Date& d);
	bool operator ==(const Date& d);
	bool operator !=(const Date& d);

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

Date::Date(int year, int month, int day)
{
	_year = year;
	_month = month;
	_day = day;
}

bool Date::operator <(const Date& d)
{
	if (_year < d._year)
	{
		return true;
	}
	else if (_year == d._year && _month < d._month)
	{
		return true;
	}
	else if (_year == d._year && _month < d._month && _day < d._day)
	{
		return true;
	}
	return false;
}
bool Date:: operator >(const Date& d)
{
	return !(*this < d || *this == d);
}
bool Date::operator <=(const Date& d)
{
	return (*this < d || *this == d);
}
bool Date::operator >=(const Date& d)
{
	return !(*this < d);
}
bool Date::operator ==(const Date& d)
{
	return _year == d._year && _month == d._month && _day == d._day;
}
bool Date::operator !=(const Date& d)
{
	return !(*this == d);
}

日期 - 日期,日期 + 天数,日期 - 天数,这些都是有意义的

cpp 复制代码
int Date::operator-(const Date& d)
{
	int sum = 0;
	if (*this > d)
	{
		if (d._year < _year)
		{
			for (int i = d._year + 1; i < _year; i++)
			{
				if ((i % 4 == 0 && i % 100 != 0) || i % 400 == 0)
				{
					sum += 366;
				}
				else
				{
					sum += 365;
				}
			}
		
		
			for (int i = d._month + 1; i <= 12; i++)
			{
				sum += GetMonthDay(d._year, i);
			}
			sum += (GetMonthDay(d._year, d._month) - d._day);

			for (int i = 1; i < _month; i++)
			{
				sum += GetMonthDay(_year, i);
			}
		}
		else if(d._year == _year)
		{
			if(d._month == _month)
				sum -= d._day;
			else
			{
				for (int i = d._month+1; i < _month; i++)
				{
					sum += GetMonthDay(_year, i);
				}
				sum += (GetMonthDay(d._year, d._month) - d._day);
			}
			
		}
		
		
		sum += _day;
	}
	else
	{
		if (_year < d._year)
		{
			for (int i = _year + 1; i < d._year; i++)
			{
				if ((i % 4 == 0 && i % 100 != 0) || i % 400 == 0)
				{
					sum -= 366;
				}
				else
				{
					sum -= 365;
				}
			}


			for (int i = _month + 1; i <= 12; i++)
			{
				sum -= GetMonthDay(_year, i);
			}
			sum -= (GetMonthDay(_year, _month) - _day);

			for (int i = 1; i < d._month; i++)
			{
				sum -= GetMonthDay(d._year, i);
			}
		}
		else if (d._year == _year)
		{
			if (d._month == _month)
				sum += _day;
			else
			{
				for (int i = _month+1; i < d._month; i++)
				{
					sum -= GetMonthDay(_year, i);
				}
				sum -= (GetMonthDay(_year, _month) - _day);
			}

		}


		sum -= d._day;
	}
	return sum;
}


Date& Date::operator+=(const int day)
{
	if (day < 0)
	{
		return *this -= -day;
	}
	_day += day;
	while (_day > GetMonthDay(_year, _month))
	{
		_day -= GetMonthDay(_year, _month);
		_month++;
		if (_month >= 13)
		{
			_year++;
			_month = 1;
		}
	}
	return *this;
}

Date Date::operator+(const int day)
{
	Date tmp = *this;
	tmp += day;
	return tmp;
}

Date& Date::operator-=(const int day)
{
	if (day < 0)
	{
		return *this += -day;
	}
	_day -= day;
	while (_day <= 0)
	{
		_day += GetMonthDay(_year, _month);
		_month--;
		if (_month <= 0)
		{
			_year--;
			_month = 12;
		}
	}
	return *this;
}
Date Date::operator-(const int day)
{
	Date tmp = *this;
	tmp -= day;
	return tmp;
}

输入(流提取)>>,输出(流插入)<< 运算符

cpp 复制代码
	//友元声明
	friend ostream& operator<<(ostream& out, const Date& d);
ostream& operator<<(ostream& out, const Date& d)
{
	out << d._year << "年" << d._month << "月" << d._day << "日" << endl;
	return out;
}
相关推荐
KyollBM20 分钟前
【CF】Day75——CF (Div. 2) B (数学 + 贪心) + CF 882 (Div. 2) C (01Trie | 区间最大异或和)
c语言·c++·算法
feiyangqingyun32 分钟前
Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
c++·qt·udp·gb28181
CV点灯大师35 分钟前
C++算法训练营 Day10 栈与队列(1)
c++·redis·算法
成工小白2 小时前
【C++ 】智能指针:内存管理的 “自动导航仪”
开发语言·c++·智能指针
sc写算法2 小时前
基于nlohmann/json 实现 从C++对象转换成JSON数据格式
开发语言·c++·json
SunkingYang2 小时前
C++中如何遍历map?
c++·stl·map·遍历·方法
Andrew_Xzw2 小时前
数据结构与算法(快速基础C++版)
开发语言·数据结构·c++·python·深度学习·算法
库库的里昂2 小时前
【C++从练气到飞升】03---构造函数和析构函数
开发语言·c++
momo卡2 小时前
MinGW-w64的安装详细步骤(c_c++的编译器gcc、g++的windows版,win10、win11真实可用)
c语言·c++·windows
凤年徐5 小时前
【数据结构初阶】单链表
c语言·开发语言·数据结构·c++·经验分享·笔记·链表