运算符重载的初识

目录

一.运算符重载

1.1 概念

2.1 运算符重载的应用

2.1.1 单目操作符

2.1.2关系操作符

2.2赋值运算符重载

2.3日期的减法

         3 总代码


一.运算符重载

1.1 概念

C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数,也具有其返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。

通俗的来说就是:内置类型(int,double),可以直接用各种运算符(=,+)

                             自定义类型,不能直接用各种运算符

                             为了自定义类型可以使用各种运算符,制定运算符重载的规则

函数名字为:关键字operator后面接需要重载的运算符符号。

函数原型:返回值类型 operator操作符(参数列表)

注意:

  • 不能通过连接其他符号来创建新的操作符:比如operator@
  • 重载操作符必须有一个类类型或者枚举类型的操作数
  • 用于内置类型的操作符,其含义不能改变,例如:内置的整型+,不 能改变其含义
  • .* 、:: 、sizeof 、?: 、. 注意以上5个运算符不能重载。

2.1 运算符重载的应用

用日期举例

#pragma once

#include <iostream>
#include <assert.h>
using std::cout;
using std::cin;
using std::endl;

class Date
{
public:
	//判断是不是闰年
	bool isLeapYear(int	year) {
		if ((year%4==0&&year%100!=0)||year%400==0)
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	// 获取某年某月的天数

	int GetMonthDay(int year, int month);
		
	// 全缺省的构造函数

	Date(int year = 2000, int month = 1, int day = 2);
		
	void Print() {
		cout << _year << "-" << _month << "-" << _day << endl;
  }
	
	// 日期-日期 返回天数

	int operator-(const Date& d);

	// 日期+=天数

	Date& operator+=(int day);

	// 日期+天数

	Date operator+(int day);

	// 日期-天数

	Date operator-(int day);

	// 日期-=天数

	Date& operator-=(int day);

	// 前置++

	Date& operator++() {
		*this += 1;
		return *this;
	}

	// 后置++

	Date operator++(int) {
		*this += 1;
		return *this;
	}

	// 后置--

	Date operator--(int) {
		*this -= 1;
		return *this;
	}

	// 前置--

	Date& operator--() {
		*this -= 1;
		return *this;
	}

	// >运算符重载

	bool operator>(const Date& d);

	// ==运算符重载

	bool operator==(const Date& d);

	// >=运算符重载

	bool  operator >= (const Date& d) {
		return *this == d || *this > d;
	}

	// <运算符重载

	 bool  operator < (const Date& d) {
		 return !(*this > d || *this == d);
	 }

	// <=运算符重载

	bool  operator <= (const Date& d) {
		return !(*this > d);
	}
	
	// !=运算符重载
	bool  operator != (const Date& d) {

		return !(*this == d);
	}

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

#include "Date.h"

int Date:: GetMonthDay(int year, int month) {
	assert(year > 0 && month > 0 && month < 13);//断言非法日期
	static int monthDayArray[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
	if (month == 2 && isLeapYear(year))
	{
		return 29;
	}
	else
	{
		return monthDayArray[month];
	}
}

 Date::Date(int year, int month, int day) {

	if (year >= 1 &&
		month <= 12 && month >= 1 &&
		day >= 1 && day <= GetMonthDay(year, month))
	{
		_year = year;
		_month = month;
		_day = day;
	}
	else
	{
		cout << "日期非法" << endl;
	}
}

2.1.1 单目操作符

单值操作数常用的有:++,--,+,- 等

注意:作为类成员的重载函数时,其形参看起来比操作数数目少1成员函数的操作符有一个默认的形参this,限定为第一个形参。

++

// 后置++

	Date operator++(int) {//这里的int没有太多意思,就等于一个信号,让编译器理解这是后置++
		Date tmp(*this);
		*this += 1;
		return tmp;
	}

// 前置++

	Date& operator++() {
		*this += 1;  
		return *this;
	}

--

// 后置--

	Date operator--(int) {
		Date tmp(*this);
		*this -= 1;
		return tmp;
	}

// 前置--

	Date& operator--() {
		*this -= 1;
		return *this;
	}

+

Date Date:: operator+(int day) {
	 Date ret = (*this);
	 ret. _day += day;
	 //判断是否要进位
	 while (ret._day>GetMonthDay(ret._year,ret._month))
	 {
		ret. _day -= GetMonthDay(ret._year, ret._month);
		ret. _month++;
		 if (ret._month==13)
		 {
			ret. _month = 1;
			 ret._year++;
		 }
	 }
	 return ret;//这种局部变量,不能用传引用返回
}

-

Date Date:: operator-(int day) {
	 if (day<0)
	 {
		 return *this + (-day);//复用+
	 }
	 Date ret = *this;
	 ret._day -= day;
	 while (ret._day<=0)
	 {
		 ret._month--;
		 if (ret._month==0)
		 {
			 ret._month = 12;
			 ret._year--;
		 }
		 ret._day += GetMonthDay(ret._year, ret._month);
	 }
	 return ret;
 }

2.1.2关系操作符

注意:作为类成员的重载函数时,其形参看起来比操作数数目少1成员函数的操作符有一个默认的形参this,限定为第一个形参。

关系操作符有:>,<,==,>=,<=等

这里代码只需要实现>.和==代码,其他就可以复用了

>

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

==

 bool Date:: operator==(const Date& d) {
	 return _year == d._year && _month == d._month
		 && _day == d._day;
}

<

// <运算符重载

	 bool  operator < (const Date& d) {
		 return !(*this > d || *this == d);
	 }

<=

// <=运算符重载

	bool  operator <= (const Date& d) {
		return !(*this > d);
	}

>=

// >=运算符重载

	bool  operator >= (const Date& d) {
		return *this == d || *this > d;
	}

!=

// !=运算符重载
	bool  operator != (const Date& d) {

		return !(*this == d);
	}

2.2赋值运算符重载

典型的赋值运算符:=,+=,-= 等。

=运算符重载是默认函数,不需要我们自己写,其他的需要我们自己写

但是有些注意:

 当然也可以写出来,代码如下:

	//=运算符重载
	Date& operator =(const Date& d) {  //用的引用减少拷贝构造
		if (this != &d)//检查是否自己给自己赋值
		{
			_year = d._year;
			_month = d._month;
			_day = d._day;
		}
		return *this;//返回值
	}

注意:这里只是浅拷贝,也就是值拷贝。

这里我们可以直接复用上面+和-的重载,写出+=和-=的重载函数

+=

Date& Date:: operator+=(int day) {
	 *this = *this + day; //复用+和=
	 return *this;
 }

-=

Date& Date:: operator-=(int day) {
	 *this = *this - day; //复用-和=
	 return *this;
 }

2.3日期的减法

日期减日期得到天数,日期加日期嗯没啥意思。

大致思路就是小的日期不断的++,直到跟大日期相等为止。

 int Date:: operator-(const Date& d) {
	 int flaght = 1;  //flaght判断是大-小,还是小-大。
	 Date max = *this; 
	 Date min = d;
	 if (*this<d) //保证大日期的max,小日期是min
	 {
		 min = *this;
		 max = d;
		 flaght = -1;
	 }
	 int count = 0;
	 while (min!=max)
	 {
		 ++count;//计数多少天相等
		 ++min;//复用前置++
	 }
	 return count*flaght; //小-大是负数
 }

3 总代码

#pragma once

#include <iostream>
#include <assert.h>
using std::cout;
using std::cin;
using std::endl;

class Date
{
public:
	//判断是不是闰年
	bool isLeapYear(int	year) {
		if ((year%4==0&&year%100!=0)||year%400==0)
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	// 获取某年某月的天数

	int GetMonthDay(int year, int month);
		
	// 全缺省的构造函数

	Date(int year = 2000, int month = 1, int day = 2);
		
	void Print() {
		cout << _year << "-" << _month << "-" << _day << endl;
  }
	
	// 日期-日期 返回天数

	int operator-(const Date& d);

	// 日期+=天数

	Date& operator+=(int day);

	// 日期+天数

	Date operator+(int day);

	// 日期-天数

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

	// 后置--

	Date operator--(int) {
		Date tmp(*this);
		*this -= 1;
		return tmp;
	}

	// 前置--

	Date& operator--() {
		*this -= 1;
		return *this;
	}

	// >运算符重载

	bool operator>(const Date& d);

	// ==运算符重载

	bool operator==(const Date& d);

	// >=运算符重载

	bool  operator >= (const Date& d) {
		return *this == d || *this > d;
	}

	// <运算符重载

	 bool  operator < (const Date& d) {
		 return !(*this > d || *this == d);
	 }

	// <=运算符重载

	bool  operator <= (const Date& d) {
		return !(*this > d);
	}
	
	// !=运算符重载
	bool  operator != (const Date& d) {

		return !(*this == d);
	}

	//=运算符重载
	Date& operator =(const Date& d) {  //用的引用减少拷贝构造
		if (this != &d)//检查是否自己给自己赋值
		{
			_year = d._year;
			_month = d._month;
			_day = d._day;
		}
		return *this;//返回值
	}
	// 日期-=天数
	Date& operator-=(int day);

private:
	int _year;
	int _month;
	int _day;
};
#include "Date.h"

int Date:: GetMonthDay(int year, int month) {
	assert(year > 0 && month > 0 && month < 13);
	static int monthDayArray[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
	if (month == 2 && isLeapYear(year))
	{
		return 29;
	}
	else
	{
		return monthDayArray[month];
	}
}


 Date::Date(int year, int month, int day) {

	if (year >= 1 &&
		month <= 12 && month >= 1 &&
		day >= 1 && day <= GetMonthDay(year, month))
	{
		_year = year;
		_month = month;
		_day = day;
	}
	else
	{
		cout << "日期非法" << endl;
	}
}



 bool Date:: operator==(const Date& d) {
	 return _year == d._year && _month == d._month
		 && _day == d._day;
}

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

 Date Date:: operator+(int day) {
	 Date ret = (*this);
	 ret. _day += day;
	 //判断是否要进位
	 while (ret._day>GetMonthDay(ret._year,ret._month))
	 {
		ret. _day -= GetMonthDay(ret._year, ret._month);
		ret. _month++;
		 if (ret._month==13)
		 {
			ret. _month = 1;
			 ret._year++;
		 }
	 }
	 return ret;
}

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

 Date Date:: operator-(int day) {
	 if (day<0)
	 {
		 return *this + (-day);//复用+
	 }
	 Date ret = *this;
	 ret._day -= day;
	 while (ret._day<=0)
	 {
		 ret._month--;
		 if (ret._month==0)
		 {
			 ret._month = 12;
			 ret._year--;
		 }
		 ret._day += GetMonthDay(ret._year, ret._month);
	 }
	 return ret;
 }

 Date& Date:: operator-=(int day) {
	 *this = *this - day;
	 return *this;
 }


 
 int Date:: operator-(const Date& d) {
	 int flaght = 1;  //flaght判断是大-小,还是小-大。
	 Date max = *this; 
	 Date min = d;
	 if (*this<d) //保证大日期的max,小日期是min
	 {
		 min = *this;
		 max = d;
		 flaght = -1;
	 }
	 int count = 0;
	 while (min!=max)
	 {
		 ++count;//计数多少天相等
		 ++min;
	 }
	 return count*flaght; //小-大是负数
 }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值