友元
1. 创建友元
有元函数的声明
创建友元函数的第一步是将其原型放在类声明中,并在原型声明前加上关键字friend:
friend Time operator*(double m, const Time & t);
该原型意味着下面两点:
- 虽然operator*()函数是在类声明中声明的,但它不是成员函数,因此不能使用成员函数运算符来调用;
- 虽然operator*()函数不是成员函数,但它与成员函数的访问权限相同。
友元函数重载示例
计算时间:
#ifndef __MYTIME4_H__
#define __MYTIME4_H__
#include <iostream>
using namespace std;
class Time
{
private:
int hours;
int minutes;
public:
Time();
Time(int h, int m = 0);
void AddMin(int m);
void AddHr(int h);
void Reset(int h = 0, int m = 0);
Time operator+(const Time &t) const;
Time operator-(const Time &t) const;
Time operator*(double mult) const;
friend Time operator*(double mult, const Time &t);
friend ostream &operator<<(ostream &os, const Time &t);
// void Show() const;
};
#endif
#include "mytime4.h"
Time::Time()
{
hours = minutes = 0;
}
Time::Time(int h, int m)
{
hours = h;
minutes = m;
}
void Time::AddMin(int m)
{
minutes += m;
hours += minutes / 60;
minutes %= 60;
}
void Time::AddHr(int h)
{
hours += h;
}
void Time::Reset(int h, int m)
{
hours = h;
minutes = m;
}
Time Time::operator+(const Time &t) const
{
Time sum;
sum.minutes = minutes + t.minutes;
sum.hours = hours + t.hours + sum.minutes / 60;
sum.minutes %= 60;
return sum;
}
Time Time::operator-(const Time &t) const
{
Time diff;
int tot1, tot2;
tot1 = hours * 60 + minutes;
tot2 = t.hours * 60 + t.minutes;
diff.hours = (tot1 - tot2) / 60;
diff.minutes = (tot1 - tot2) % 60;
return diff;
}
Time Time::operator*(double mult) const
{
Time result;
long totalminutes = hours*mult*60 + minutes*mult;
result.hours = totalminutes / 60;
result.minutes = totalminutes % 60;
return result;
}
/*
void Time::Show() const
{
cout << hours << " hours, " << minutes << " minutes." << endl;
}
*/
Time operator*(double mult, const Time &t)
{
Time result;
long totalminutes = t.hours*mult*60 + t.minutes*mult;
result.hours = totalminutes / 60;
result.minutes = totalminutes % 60;
return result;
}
ostream &operator<<(ostream &os, const Time &t)
{
os << t.hours << " hours, " << t.minutes << " minutes." << endl;
return os;
}
/*
Time operator*(double mult, const Time &t)
{
return t * mult;
}
*/
#include <iostream>
#include "mytime4.h"
using namespace std;
int main(void)
{
Time coding(4, 35);
Time fixing(2, 47);
Time total;
Time Planning;
Time diff;
Time adjusted;
cout << "coding time = ";
// coding.Show();
cout << coding;
cout << "fixing time = ";
// fixing.Show();
cout << fixing;
total = coding + fixing;
// total.Show();
cout << total;
diff = coding - fixing;
// diff.Show();
cout << diff;
adjusted = coding * 1.5;
// adjusted.Show();
cout << adjusted;
adjusted = 1.5 * coding;
// adjusted.Show();
cout << adjusted;
cout << "************************" << endl;
cout << coding << fixing;
return 0;
}
运行结果:
➜ C++ g++ main.cpp mytime4.cpp
➜ C++ ./a.out
coding time = 4 hours, 35 minutes.
fixing time = 2 hours, 47 minutes.
7 hours, 22 minutes.
1 hours, 48 minutes.
6 hours, 52 minutes.
6 hours, 52 minutes.
************************
4 hours, 35 minutes.
2 hours, 47 minutes.
2. 常用的友元:重载<<运算符
- << 的第一种重载版本
void operator<<(ostream & os, const Time & t)
{
os << t.hours << " hours, " << t.minutes << " minutes";
}
- << 的第二种重载版本
ostream & operator<<(ostream & os, const Time & t)
{
os << t.hours << " hours, " << t.minutes << " minutes";
return os;
}
3. 友元和成员函数在重载运算符上的区别
非成员版本的重载运算符函数所需的形参数目与运算符使用的操作数数目相同,而成员函数所需的参数数目少一个,因为其中的一个操作数是被隐式地传递的调用对象。
加法运算符需要两个操作数。对于成员函数版本来说,一个操作数通过this指针隐式地传递,另一个操作数作为函数参数显式地传递;对于友元版本来说,两个操作数都作为参数来传递。