运算符重载与友元

参考:《C++Primer Plus》第六版

计算时间:一个运算符重载示例

先给段代码:

#include<iostream>
#include<string>
using namespace std;
class Time {
private:	
	int hours;
	int minutes;
public:
	Time(int hr = 0, int min = 0) :hours(hr), minutes(min) {}
	void AddMin(int m) { minutes += m;hours += minutes / 60;minutes %= 60; }
	void AddHr(int h) { hours += h; }
	void Reset(int h = 0, int m = 0) { hours = h; minutes = m; }
	Time Sum(const Time &t)const { 
		Time sum;
		sum.minutes = minutes + t.minutes;
		sum.hours = t.hours + hours + sum.minutes / 60;
		sum.minutes %= 60;
		return sum;
	}
	void Display() { cout << hours << ' ' << minutes << endl; }
	~Time() {}
};
int main()
{
	Time t1(3, 55), t2(2, 6), tt;
	tt = t1.Sum(t2);
	tt.Display();
	system("pause");
	return 0;
}

这段代码用来计算两个时间的加和,需要使用函数对象的方式进行调用并赋值。我们如果想要用加减号等进行时间的计算,这就引入了运算符重载的概念。C++允许将运算符重载到用户定义的类型,例如,允许使用+将两个对象相加。

运算符重载

做法:
将上面代码Time类中的Time Sum(const Time &t)const 这段声明改为 Time operator+(const Time &t)const即可。
tips:

  • operator中文释义:运算符

  • 重载的一般形式:<返回类型说明符> operator <运算符符号>(<参数表>) { … }

  • 在主函数中调用时,tt = t1 + t2 相当于如下语句: tt = t1.operator+(t2),也就是说,运算符左侧的对象作为函数的调用者,后面的对象则作为实参传递给被调用的对象。

友元

友元:

  1. 什么是友元:友元是一种定义在类外部的普通函数或类,但它需要在类体内进行说明,它不属于成员函数,但是可以访问类中的私有成员。
  2. 什么时候使用友元进行运算符重载:多在重载二元运算符时使用(带两个参数的运算符)

示例:仍回到上面的代码,如果进行如下运算,程序将会报错:没有与这些操作匹配的“+”运算符

tt = 3 + t2;

为什么呢?不妨将这个式子转化为另外一种形式:tt = 3.operator(t2)
这样就很明了了!很显然,3不是一个Time型的对象,因此无法使用Time类的成员函数。

友元的引入

针对上面提出的问题,可能想到的一种解决措施是在外部新创建一个非成员函数,它的声明如下:

扫描二维码关注公众号,回复: 4277821 查看本文章
Time operator+(int n,const Time &t);

随之而来的问题是,基于类的封装性,外部非成员函数不能直接访问类的私有数据。那么该如何做呢?回顾上面关于友元的定义,我们发现可以使用友元来解决这个问题。
步骤:
(1)类中的声明:

friend Time operator+(int n, const Time &t);

类外的定义:
需要特别强调的是,因为友元函数不是成员函数,因此在外部的定义中无需加friend

Time operator+(int n, const Time &t)
{
	Time sum;
	sum.hours = n + t.hours;
	sum.minutes = t.minutes;
	return sum;
}

常用的友元:重载<<运算符

这里由于时间原因简写,等有时间补上。
对于count<<t1<<endl;
其重载的类内声明:
friend ostream & operator<<(ostream &os, const Time &t);
外部定义:

ostream & operator<<(ostream &os, const Time &t)	//因为cout是ostream对象,故返回类型为ostream的引用
{
	os << t.hours << ' ' << t.minutes;
	return os;
}

全部代码:

#include<iostream>
#include<string>
using namespace std;
class Time {
private:	
	int hours;
	int minutes;
public:
	Time(int hr = 0, int min = 0) :hours(hr), minutes(min) {}
	void AddMin(int m) { minutes += m;hours += minutes / 60;minutes %= 60; }
	void AddHr(int h) { hours += h; }
	void Reset(int h = 0, int m = 0) { hours = h; minutes = m; }
	/*Time operator+(const Time &t)const { 
		Time sum;
		sum.minutes = minutes + t.minutes;
		sum.hours = t.hours + hours + sum.minutes / 60;
		sum.minutes %= 60;
		return sum;
	}*/
	friend ostream & operator<<(ostream &os, const Time &t);
	void Display() { cout << hours << ' ' << minutes << endl; }
	~Time() {}
};
int main()
{
	Time t1(3, 55), t2(2, 6), tt;
	//tt.Display();
	cout << t1 << endl;
	system("pause");
	return 0;
}
ostream & operator<<(ostream &os, const Time &t)	//因为cout是ostream对象,故返回类型为ostream的引用
{
	os << t.hours << ' ' << t.minutes;
	return os;
}

猜你喜欢

转载自blog.csdn.net/cprimesplus/article/details/83934791
今日推荐