运算符重载和重载函数

1.运算符重载的意义

C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数,也具有其返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。
函数名字为:关键字operator后面接需要重载的运算符符号。
函数原型:返回值类型 operator操作符(参数列表)

当您调用一个重载函数或重载运算符时,编译器通过把您所使用的参数类型与定义中的参数类型进行比较,决定选用最合适的定义。选择最合适的重载函数或重载运算符的过程,称为重载决策。

在同一个作用域内,可以声明几个功能类似的同名函数,但是这些同名函数的形式参数(指参数的个数、类型或者顺序)必须不同。您不能仅通过返回类型的不同来重载函数。

注意:

  • 不能通过连接其他符号来创建新的操作符:比如operator@
  • 重载操作符必须有一个类类型参数
  • 用于内置类型的运算符,其含义不能改变,例如:内置的整型+,不 能改变其含义
  • 作为类成员函数重载时,其形参看起来比操作数数目少1,因为成员函数的第一个参数为隐藏的this
  • .* sizeof ?: . :: #注意以上6个运算符不能重载。切记

2.运算符重载的使用

通过实现一个日期类函数,学习运算符重载的使用

先来写一个类用来实现日期类的创建

class Date
{
    //友元函数
	friend ostream& operator<<(ostream& out, const Date& date);
	friend ostream& operator>>(istream& in, Date& date);
public:
	Date(int year = 0, int month = 0, int day = 0)
	{
		_year = year;
		_month = month;
		_day = day;
		cout << "创建" << _year << endl;
	}

	~Date()
	{
		cout << "销毁" << _year << endl;
	}
	//拷贝构造函数
	Date(Date& date)
	{
		cout << "1" << endl;
		_year = date._year;
		_month = date._month;
		_day = date._day;
	}
	//void Print();
	//判断两个日期是否相等
	bool operator==(const Date& days);
    //判断前一个日期是否大于等于后一个日期
	bool operator>=(const Date& days);
    //判断前一个日期是否小于等于后一个日期
	bool operator<=(const Date& days);
    //判断前一个日期是否大于后一个日期
	bool operator>(const Date& days);
    //判断前一个日期是否小于后一个日期
	bool operator<(const Date& days);
    //判断两个日期是否不相等
	bool operator!=(const Date& days);

    //日期加一个天数,返回一个日期,改变原日期
	Date& operator+=(int days);
    //日期加一个天数,返回另一个日期,原日期不变
	Date operator+(int days);
    //日期减天数,返回一个日期,原日期改变
	Date& operator-=(int days);
    //日期减日期,返回一个天数
	int operator-=(Date& days);
    
    Date& operator--();
	Date& operator--(int) ;
	Date& operator++();
	Date& operator++(int) ;



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

//重载流提取
ostream& operator<<(ostream& out, const Date& date);
//重载流插入
ostream& operator>>(istream& in, Date& date);

3.友元函数:(临时插入)

类的友元函数是定义在类外部,但有权访问类的所有私有(private)成员和保护(protected)成员。尽管友元函数的原型有在类的定义中出现过,但是友元函数并不是成员函数。

友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元类,在这种情况下,整个类及其所有成员都是友元。

如果要声明函数为一个类的友元,需要在类定义中该函数原型前使用关键字 friend。

注意:友元提供了一种突破封装的方式,有时提供了便利。但是友元会增加耦合度,破坏了封装,所以友元不宜多用。

说明:

  • 友元函数可访问类的私有和保护成员,但不是类的成员函数
  • 友元函数不能用const修饰
  • 友元函数可以在类定义的任何地方声明,不受类访问限定符限制
  • 一个函数可以是多个类的友元函数
  • 友元函数的调用与普通函数的调用原理相同
     

友元类下次再说

4.日期类函数的实现

4.1打印函数

/打印函数,用下面的流插入流体取实现
//void Date::Print()
//{
//	cout << _year << " "
//		<< _month << " "
//		<< _day << endl;
//}

4.2 比较运算符的实现

//相等
bool Date::operator==(const Date& days) const
{
	return _year == days._year &&
		_month == days._month &&
		_day == days._day;
}
//大于
bool Date::operator>(const Date& days) const
{
	if (_year > days._year)
	{
		return true;
	}
	else if (_year == days._year &&
		_month > days._month)
	{
		return true;
	}
	else if (_year == days._year &&
		_month == days._month &&
		_day > days._day)
	{
		return true;
	}
	return false;
}
//小于
bool Date::operator<(const Date& days) const
{
	return !(*this > days && *this == days);
}
//大于等于
bool Date::operator>=(const Date& days) const
{
	return (*this > days)|| (*this == days);
}
//小于等于
bool Date::operator<=(const Date& days) const
{
	return !(*this > days);
}
//不等于
bool Date::operator!=(const Date& days) const
{
	return !(*this == days);
}

4.3加减法的实现

//判断一个月的天数
int GetMonthDay(int _year, int _month)
{
	static int monthday[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 monthday[_month];
}	
//日期加一个天数
Date& Date::operator+=(const int days)
{
	_day += days;
	while (_day > GetMonthDay(_year, _month))
	{
		_day -= GetMonthDay(_year, _month);
		_month++;
		if (_month == 13)
		{
			_year++;
			_month = 1;
		}
	}
	return *this;
}
//日期加天数,本身不变
Date Date::operator+(const int days)
{
	Date tmp(*this);
	tmp += days;
	return tmp;
}
//日期减天数,本身改变
Date& Date::operator-=(int days)
{
	if (days < _day)
	{
		_day -= days;
		return *this;
	}

	else if (days == _day)
	{
		_month -= 1;
		if (_month == 0)
		{
			_month = 12;
			_year--;
		}
		_day = GetMonthDay(_year, _month);
		return *this;
	}
	else
	{
		days -= _day;
		_month -= 1;
		if (_month == 0)
		{
			_month = 12;
			_year -= 1;
		}
		while (days > GetMonthDay(_year, _month))
		{
			_month -= 1;
			if (_month == 0)
			{
				_month = 12;
				_year -= 1;
			}
		}
		return *this;
	}
	
}
Date Date::operator-(int days)
{
	Date tmp(*this);
	tmp -= 1;
	return tmp;
}
//日期减日期
int  Date::operator-=(Date& days)
{
	//int days = 0;
	if (*this > days)
	{
		if(_day>days._day)
			return _day - days._day;
		else
		{
			return _day + GetMonthDay(_year, _month - 1) - days._day;
		}
	}
	else if (*this == days)
	{
		return 0;
	}
	else
	{
		if (_day < days._day)
			return days._day-_day;
		else
		{
			 return days._day+ GetMonthDay(_year, _month - 1) - _day;
		}
	}

}
//前置日期减减
Date& Date::operator--()
{
	*this -= 1;
	return *this;
}
//后置减减,后置加加需要传一个int,语法规定,后置加加也一样
Date& Date::operator--(int)
{
	Date tmp(*this);
	tmp -= 1;
	return *this;
}
//前置加加
Date& Date::operator++()
{
	*this += 1;
	return *this;
}
//后置加加
Date& Date::operator++(int)
{
	Date tmp(*this);
	tmp += 1;
	return *this;
}

4.4流提取和流插入

//流插入
ostream& operator<<(ostream& out, const Date& date)
{
	out << date._year << "年"
		<< date._month << "月"
		<< date._day << "日"
		<< endl;
	return out;
}
//流提取
ostream& operator>>(istream& in, Date& date)
{
	in >> date._year >> date._month >> date._day;
	return cout<<date;
}

这是运算符重载和重载函数的实现,有兴趣的可以自己敲一下。


 

评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

函数指针

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值