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;
}
相关推荐
专注VB编程开发20年2 小时前
除了 EasyXLS,加载和显示.xlsx 格式的excel表格,并支持单元格背景色、边框线颜色和粗细等格式化特性
c++·windows·excel·mfc·xlsx
夏天的阳光吖3 小时前
C++蓝桥杯基础篇(四)
开发语言·c++·蓝桥杯
oioihoii4 小时前
C++17 中的 std::to_chars 和 std::from_chars:高效且安全的字符串转换工具
开发语言·c++
张胤尘4 小时前
C/C++ | 每日一练 (2)
c语言·c++·面试
強云5 小时前
23种设计模式 - 装饰器模式
c++·设计模式·装饰器模式
yatingliu20195 小时前
代码随想录算法训练营第六天| 242.有效的字母异位词 、349. 两个数组的交集、202. 快乐数 、1. 两数之和
c++·算法
鄃鳕6 小时前
单例模式【C++设计模式】
c++·单例模式·设计模式
只做开心事6 小时前
C++之特殊类设计
开发语言·c++
宋康6 小时前
C/C++ 指针避坑20条
c语言·开发语言·c++
Ryan_Gosling6 小时前
C++-构造函数-接口
开发语言·c++