运算符重载和重载函数

这篇具有很好参考价值的文章主要介绍了运算符重载和重载函数。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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;
}

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


 文章来源地址https://www.toymoban.com/news/detail-458126.html

到了这里,关于运算符重载和重载函数的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C++】:拷贝构造函数和赋值运算符重载

    拷贝构造函数是特殊的构造函数。 是用一个已经存在的对象,赋值拷贝给另一个新创建的已经存在的对象 。 本质:用同类型的对象拷贝初始化 。 拷贝构造函数也是 特殊的成员函数 ,其特征如下: 2.1 拷贝构造函数是构造函数的一个重载形式。 2.2 拷贝构造函数的 函数名域

    2024年04月28日
    浏览(31)
  • C++拷贝构造函数与赋值运算符重载

    顾得泉: 个人主页 个人专栏: 《Linux操作系统》 《C++从入门到精通》  《LeedCode刷题》 键盘敲烂,年薪百万!        在现实生活中,可能存在一个与你一样的自己,我们称其为双胞胎。        那在创建对象时,可否创建一个与已存在对象一某一样的新对象呢?  

    2024年02月22日
    浏览(38)
  • kotlin学习(二)泛型、函数、lambda、扩展、运算符重载

    Kotlin 中的类可以有类型参数,与 Java 类似: 创建这样类的实例只需要提供类型参数即可: 如果类型参数可以推断出来,例如从构造函数的参数或者从其他途径,就可以省略类型参数: String作为Object的子类,就可以直接将子类对象赋值给父类,这个操作即达到了 型变 。 但是

    2024年02月09日
    浏览(29)
  • 运算符重载的函数作为类的成员函数和友元函数

    🐶博主主页: @ᰔᩚ. 一怀明月ꦿ  ❤️‍🔥 专栏系列: 线性代数,C初学者入门训练,题解C,C的使用文章,「初学」C++ 🔥 座右铭: “不要等到什么都没有了,才下定决心去做” 🚀🚀🚀大家觉不错的话,就恳求大家点点关注,点点小爱心,指点指点🚀🚀🚀 目录 🐰运

    2024年02月08日
    浏览(27)
  • 【C++】构造函数,析构函数,拷贝构造,运算符重载,const 成员

    默认成员函数:如果不显示,编译器默认生成 构造函数:是一个特殊的 成员函数 ,函数名与类名相同,专门用于 初始化类对象 函数名与类名相同 无返回值 ,没有被声明为void类型 对象实例化时 编译器自动调用 , Date d1 ,或 Date d2(2023, 4, 21) 构造函数可以重载,一个类中可以

    2023年04月24日
    浏览(57)
  • 【C++】类和对象(中)---拷贝构造函数、赋值运算符重载

    个人主页:平行线也会相交💪 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 平行线也会相交 原创 收录于专栏【C++之路】💌 本专栏旨在记录C++的学习路线,望对大家有所帮助🙇‍ 希望我们一起努力、成长,共同进步。🍓 拷贝构造函数,又称复制构造函数,是一种特殊的

    2024年02月05日
    浏览(38)
  • C++ -3- 类和对象 (中) | 拷贝构造函数 & 赋值运算符重载

    示例: 拷贝初始化构造函数的作用是将一个已知对象的数据成员值拷贝给正在创建的另一个同类的对象 无穷递归 ? Date(Date d){……} 首先,分析 传值传参的过程 传引用传参 : 没有拷贝 的过程,直接传 传值传参: 内置类型 编译器可以直接拷贝(浅拷贝/值拷贝——一个字节

    2023年04月19日
    浏览(69)
  • 【C++】C++入门—初识构造函数 , 析构函数,拷贝构造函数,赋值运算符重载

    如果一个类中什么成员都没有,简称为空类。 空类中真的什么都没有吗? 并不是 任何类在什么都不写时,编译器会自动生成以下6个默认成员函数。 默认成员函数:用户没有显式实现,编译器会生成的成员函数称为默认成员函数 我们实现了,编译器就不会生成了 构造函数是

    2024年02月21日
    浏览(40)
  • 【C++】:类和对象(中)之拷贝构造函数+赋值运算符重载

    在现实生活中,可能存在一个与你一样的自己,我们称其为双胞胎 那在创建对象时,可否创建一个与已存在对象一某一样的新对象呢? 拷贝构造函数:只有单个形参,该形参是对本类类型对象的引用(一般常用const修饰),在用已存在的类类型对象创建新对象时由编译器自动调

    2024年02月06日
    浏览(39)
  • 【C++】类和对象③(类的默认成员函数:拷贝构造函数 | 赋值运算符重载)

    🔥 个人主页: Forcible Bug Maker 🔥 专栏: C++ 目录 前言 拷贝构造函数 概念 拷贝构造函数的特性及用法 赋值运算符重载 运算符重载 赋值运算符重载 结语 本篇主要内容:类的6个默认成员函数中的 拷贝构造函数 和 赋值运算符重载 在上篇文章中我们讲到了类的默认成员函数的

    2024年04月17日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包