参考:《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),也就是说,运算符左侧的对象作为函数的调用者,后面的对象则作为实参传递给被调用的对象。
友元
友元:
- 什么是友元:友元是一种定义在类外部的普通函数或类,但它需要在类体内进行说明,它不属于成员函数,但是可以访问类中的私有成员。
- 什么时候使用友元进行运算符重载:多在重载二元运算符时使用(带两个参数的运算符)
示例:仍回到上面的代码,如果进行如下运算,程序将会报错:没有与这些操作匹配的“+”运算符
tt = 3 + t2;
为什么呢?不妨将这个式子转化为另外一种形式:tt = 3.operator(t2)
这样就很明了了!很显然,3不是一个Time型的对象,因此无法使用Time类的成员函数。
友元的引入
针对上面提出的问题,可能想到的一种解决措施是在外部新创建一个非成员函数,它的声明如下:
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;
}