友元

在了解友元之前,我们需要知道为什么需要友元
在为类重载二元运算符时常常需要友元。

假设Time是我们自己定义的关于时间的类,现在要重载乘法运算符,使得Time值可以与一个double值相乘。但是如果用成员函数重载乘法运算符,左侧的操作数是调用对象,也就是说,下面的语句:

A = B * 2.75;

将被转换成下面的成员函数调用:

A = B.operator * (2.75); 

但是下面的语句又会怎么样呢?

A = 2.75*B;

因为2.75不是Time类型的对象,因此,编译器不能使用成员函数来替换该表达式。

这时候,我们还有另外一种方式----非成员函数。非成员函数不是由对象调用的,它使用的所有值(包括对象)都是显式参数。这样子,编译器就能够将下面的表达式:

A = 2.75*B;

与下面的非成员函数调用匹配:

A = operator * (2.75, B);

该非成员函数的原型如下:

Time operator * (double m, const Time& t);

但是这个时候又出现了新的问题,常规的非成员函数不能直接访问类的私有成员。有一类特殊的非成员函数可以访问类的私有成员,它们被成为友元函数。


创建友元函数第一步是将原型放在类声明中,并且在原型声明前加上关键字friend:

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 n) const;
    void Show() const;
    friend Time operator * (double m, const Time& t);
}; 

第二步是编写函数定义。因为它不是成员函数,所以不要使用Time::限定符。另外,不要在定义中使用friend, 定义应该如下:

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;
}

有了上述声明和定义后,下面的语句:
A = 2.75*B;
将转换成如下语句,从而调用刚才定义的非成员友元函数:
A = operator * ( 2.75, B);
总之,类的友元函数是非成员函数,其访问权限与成员函数相同。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值