运算符重载

言简意赅:对象也可以做加减乘除等运算。

对象,也可以说是结构体,怎么做到像 C 里的运算符那样运算方便呢。有问题就会有方法。再自定义一个函数,然后根据相应的运算符重载一下,就可以实现对应功能了。

这个知识点可以说很重要,因为他实现了像日期类对象等可以直接加减的运算,大大加强了效率。

对象并没有平时常用运算符(只有赋值可以用),所以要自己一个一个敲出来。

一等:

我们先看第一种:
 

class Data
{
public:
	Data(int year = 1, int month = 0, int day = 0)
	{
		_year = year;
		_month = month;
		_day = day;
	}
private:
	int _year;
	int _month;
	int _day;
};

bool operator==(const Data& d1, const Data& d2)
{
	return d1._year == d2._year
		&& d1._month == d2.month                   //报错 访问错误
		&& d1._day == d2._day;
}

int main()
{
	Data d1(2023,5,2);
	Data d2(2023,5,2);

	return 0;
}

根据上面的错位,所以一般运算符重载的函数都是放在类里。像这样:

class Data
{
public:
	Data(int year = 1, int month = 0, int day = 0)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	bool operator==(const Data& d1, const Data& d2)
	{
		return d1._year == d2._year
			&& d1._month == d2.month
			&& d1._day == d2._day;
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Data d1(2023,5,2);
	Data d2(2023,5,2);

	return 0;
}

可是直接放里呢,又会说  E0344    此运算符函数的参数太多 原因呢,就和拷贝构造函数一样,是带有隐形参数的,就是赋值对象,就是主比较对象,我愿意叫他主对象。所以写法就是这样:

class Data
{
public:
	Data(int year = 1, int month = 0, int day = 0)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	bool operator==(const Data& d)
	{
		return _year == _year
			&& _month == _month
			&& _day == _day;
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Data d1(2023,5,2);
	Data d2(2023,5,2);

	cout << d1.operator==(d2) << endl;

	return 0;
}

接下来呢,就说下需要注意的地方:

00xx00:.* :: sizeof ?:  .  这五个运算符是不能重载的
00xx01:不能创建新的操作符
00xx02:必须有一个类类型参数
00xx03:含义不能改变
00xx04:参数少一 隐藏参数this

二等:

=:

现在再说下相等 = 也就是赋值

Data& operator=(const Data& d)

{

        if (this != &d)

        {

                _year = d._year;

                _month = d._month;

                _day = d._day;

        } 

        return *this;
}

这个if判断呢,就是防止有人让自己等于自己,这里再说下隐藏参数的问题,就是第一个参数是this,被隐藏了,所以传参和写参数时直接从第二个开始写就可以了。

++/--:

这里需要注意的最后一个点呢就是++,因为++有前置的,也有后置的。在写的时候函数的写法是一样的。所以我们可以做这样一个处理,让这个函数构成重载:

Data& operator++()      //前置++

Data operator++(int)    //后置++

这里明显看出两个区别,先说 int 效果就是让函数构成重载,并没有实质意义,第二个区别 & 前置++是先++在返回,可以把参数直接带回去,后置呢,是先返回再++,所以不能直接带回去,建立一个变量带回去。 -- 也是同理,其他类型也是如此。  

三等:

<</>>:

先说流插入(<</cout),平时用流插入的时候,可以自动识别类型去直接输出,具体原因如下:

cout.operator<<(i) // int

cout.operator<<(d) // double

再回来看这个重载是怎么玩的

class Data
{
public:
	Data(int year = 1, int month = 0, int day = 0)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	bool operator==(const Data& d)
	{
		return _year == _year
			&& _month == _month
			&& _day == _day;
	}
	void operator<<(ostream& out)
	{
		out << _year << " " << _month << " " << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};



int main()
{
	Data d1(2023,5,2);
	Data d2(2023,5,2);

	cout << d1.operator==(d2) << endl;

	//cout << d1;
	d1.operator<<(cout);

	return 0;
}

运行结果如下

发现他并不能像平时那么使用,而是调用,原因呢 也很简单,就是需要私有里的数据,那有没有把他拿出来使用同时还能访问私有的方法呢,方法 自然就有 (站着 还能把钱赚了)

class Data
{
	friend void operator<<(ostream& out, const Data& d)
	{
		out << d._year << " " << d._month << " " << d._day << endl;
	}
public:
	Data(int year = 1, int month = 0, int day = 0)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	bool operator==(const Data& d)
	{
		return _year == _year
			&& _month == _month
			&& _day == _day;
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Data d1(2023,5,2);
	Data d2(2023,5,2);

	//cout << d1.operator==(d2) << endl;

	cout << d1;
	//d1.operator<<(cout);


	return 0;
}

设置成友元函数就行了,you are my friend ,但是这样就少了一种功能:

cout << d1 << d2 << endl

原因呢,就是在返回值这里,没有返回值,怎么能连续插入呢

class Data
{
	friend ostream& operator<<(ostream& out, const Data& d)
	{
		out << d._year << " " << d._month << " " << d._day << endl;
		return out;
	}
public:
	Data(int year = 1, int month = 0, int day = 0)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	bool operator==(const Data& d)
	{
		return _year == _year
			&& _month == _month
			&& _day == _day;
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Data d1(2023,5,2);
	Data d2(2023,5,2);

	//cout << d1.operator==(d2) << endl;

	//cout << d1;
	//d1.operator<<(cout);
	cout << d1 << d2 << endl;


	return 0;
}

大家自行测试就好了。

然后是流提取,有了流插入,流提取就好说多了。

大家直接结合cplusplus看代码就行了,注意 d 的const。

class Data
{
	friend ostream& operator<<(ostream& out, const Data& d)
	{
		out << d._year << " " << d._month << " " << d._day << endl;
		return out;
	}
	friend istream& operator>>(istream& in, Data& d)
	{
		in >> d._year >> d._month >> d._day;
		return in;
	}
public:
	Data(int year = 1, int month = 0, int day = 0)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	bool operator==(const Data& d)
	{
		return _year == _year
			&& _month == _month
			&& _day == _day;
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Data d1(2023,5,2);
	Data d2(2023,5,2);

	//cout << d1.operator==(d2) << endl;

	//cout << d1;
	//d1.operator<<(cout);
	cout << d1 << d2 << endl;

	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值