C++类和对象(中)【下篇】

  🌟个人主页:落叶

  🌟当前专栏:  C++专栏


目录

赋值运算符重载

运算符重载

赋值运算符重载

日期类实现

运算符重载<和运算符重载==

运算符重载进行复用

运算符重载<=

运算符重载>=

运算符重载>

运算符重载!=

获取某年某月的天数

日期+=或+天数

日期-=或-天数

前置++和后置++

日期-日期

日期类实现代码 

Date.h

Date.cpp

test.cpp 

 运算符重载的(流插入和流提取)

流插入

流提取 

 取地址运算符重载

const成员函数

取地址运算符重载


赋值运算符重载

运算符重载

  • 当运算符被⽤于类类型的对象时,C++语⾔允许我们通过运算符重载的形式指定新的含义。C++规定类类型对象使⽤运算符时,必须转换成调⽤对应运算符重载,若没有对应的运算符重载,则会编译报错。

  • 运算符重载是具有特殊名字的函数,他的名字是由operator和后⾯要定义的运算符共同构成。和其他函数⼀样,它也具有其返回类型和参数列表以及函数体。

  • 重载运算符函数的参数个数和该运算符作⽤的运算对象数量⼀样多。⼀元运算符有⼀个参数( 如:*/++/-- ),⼆元运算符有两个参数 (如: +/- />/<) ,⼆元运算符的左侧运算对象传给第⼀个参数,右侧运算对象传给第⼆个参数。

  • 如果⼀个重载运算符函数是成员函数,则它的第⼀个运算对象默认传给隐式的this指针,因此运算符重载作为成员函数时,参数⽐运算对象少⼀个。

  • 运算符重载以后,其优先级结合性对应的内置类型运算符保持⼀致

  • 不能通过连接语法中没有的符号来创建新的操作符:⽐如operator@

  • .*    ::     sizeof       ?:     . ?  注意以上5个运算符不能重载。(选择题⾥⾯常考,⼤家要记下)

  • 重载操作符⾄少有⼀个类类型参数,不能通过运算符重载改变内置类型对象的含义,如: int  operator+(int  x, int  y)

  • ⼀个类需要重载哪些运算符,是看哪些运算符重载后有意义,⽐如Date类(日期类)重载operator-就有意义,日期减去日期可以得到还剩下但是天。

    但是重载operator*就没有意义。

  • 重载++运算符时,有前置++和后置++,运算符重载函数名都是operator++,⽆法很好的区分。C++规定,后置++重载时,增加⼀个int形参,跟前置++构成函数重载,⽅便区分。

  • 重载<<和>>时,需要重载为全局函数,因为重载为成员函数,this指针默认抢占了第⼀个形参位置,第⼀个形参位置是左侧运算对象,调⽤时就变成了 对象<<cout,不符合使⽤习惯和可读性。重载为全局函数把ostream/istream放到第⼀个形参位置就可以了,第⼆个形参位置当类类型对象。

内置类型(int...)这些支持编译器自带的运算符,但是自定义类型(类类型...)这些,就不支持运算符了。

自定义类型,编译器不知道我们定义的自定义类型是什么要干什么。

所以编译器让我们自己根据自定义类型来实现运算符重载

下面那个代码是比较2个日期类大小,用运算符重载函数(operator和运算符结合)来进行比较。

重载操作符⾄少有⼀个类类型参数,不能通过运算符重载改变内置类型对象的含义,如: int  operator+(int  x, int  y)

重载运算符函数的参数个数和该运算符作⽤的运算对象数量⼀样多。⼀元运算符有⼀个参数( 如:*/++/-- ),⼆元运算符有两个参数 (如: +/- />/<) ,⼆元运算符的左侧运算对象传给第⼀个参数,右侧运算对象传给第⼆个参数。

下面这个代码私有的成员变量,不能被修改,所以会报错,公有就不会报错,也可以重载为成员函数

#include<iostream>
using namespace std;
class Date
{
public://公有

	//全缺省构造函数
	Date(int year = 1, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}

private:私有

//成员变量
	int _year;//年
	int _month;//月
	int _day;//日
};

//--------------------------------------------------------------------

bool operator<(const Date& x1, const Date& x2)
{
	//比较年
	if (x1._year < x2._year)
	{
		return true;
	}
	//年相等,比较月
	else if (x1._year == x2._year && x1._month < x2._month)
	{
		return true;
	}
	//年相等,月相等,比较日
	else if (x1._year == x2._year && x1._month == x2._month && x1._day < x2._day)
	{
		return true;
	}
	//都等于,或大于返回false
	return false;
}

int main()
{
	Date d1(2024, 9, 2);
	Date d2(2024, 7, 4);
	//比较,结果给tab
	bool tab2 = operator<(d1, d2);
	//这样写,编译器会自动转换成operator<(d1, d2),所以这样写比较方便
	bool tab = d1 < d2;

	cout << tab << endl;

	return 0;
}

重载为成员函数

重载为成员函数,就不能向上面这样写了。

我们可以看到下面报错了很多。运算符函数参数太多。

如果⼀个重载运算符函数是成员函数,则它的第⼀个运算对象默认传给隐式的this指针,因此运算符重载作为成员函数时,参数⽐运算对象少⼀个。 

有隐式的this指针,所以我们不需要显示写d1这个参数。

#include<iostream>
using namespace std;
class Date
{
public:

	//全缺省构造函数
	Date(int year = 1, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}

	//不用写第一个参数,第一个参数有隐式的this指针
	bool operator<( const Date& x2)
	{
		//比较年
		if (_year < x2._year)
		{
			return true;
		}
		//年相等,比较月
		else if (_year == x2._year && _month < x2._month)
		{
			return true;
		}
		//年相等,月相等,比较日
		else if (_year == x2._year && _month == x2._month && _day < x2._day)
		{
			return true;
		}
		//都等于,或大于返回false
		return false;
	}

private:
	int _year;//年
	int _month;//月
	int _day;//日
};

int main()
{
	Date d1(2024, 9, 2);
	Date d2(2024, 7, 4);
	//比较,结果给tab
	bool tab2 = d1.operator<(d2);
	//这样写编译器会转换成       d1.operator<(d2),    所以这样写比较方便
	bool tab = d1 < d2;

	cout << tab << endl;

	return 0;
}

这个d1类里的operator<函数,把d2传过去,这样就可以对2个类进行比较了。

也可以这样写。

//这样写编译器会转换成       d1.operator<(d2),    所以这样写比较方便
	bool tab = d1 < d2;

我们可以看到它们在汇编,都是一样的。


.*    ::     sizeof       ?:     . ?  注意以上5个运算符不能重载。(选择题⾥⾯常考,⼤家要记下)。

class A
{
public:
	//成员函数
	void func()
	{
		cout << "A::func()" << endl;
	}
};
typedef void(A::* PF)(); //成员函数指针类型

int main()
{
	// C++规定成员函数要加&才能取到函数指针
	PF pf = &A::func;

	A obj; //定义ob类对象temp

	// 对象调⽤成员函数指针时,使⽤.*运算符
	(obj.*pf)();

	return 0;
}


重载操作符⾄少有⼀个类类型参数,不能通过运算符重载改变内置类型对象的含义,如: int  operator+(int  x, int  y)

// 编译报错:“operator +”必须⾄少有⼀个类类型的形参
int operator+(int x, int y)
{
return x - y;
}

重载++运算符时,有前置++后置++,运算符重载

评论 250
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

落叶 

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

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

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

打赏作者

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

抵扣说明:

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

余额充值