通常,cpp公有类方法是访问类对象私有部分的唯一途径,但是有时种限制太严格,以致于不适合特定的编程问题。在这种情况下,cpp提供了另外一种形式的访问权限:友元。
通过让函数成为类的友元,可以赋予该函数与类的成员函数相同的访问权限。
需要使用友元的情况(案例)
class Time
{
private:
...
public:
...
// *运算符重载
Time operator*(double n) const;
};
Time time1;
Time time2;
// 使用*运算符重载
time1 = time2 * 0.9;
问题
由于运算符*
左侧的操作数是调用对象,也就是说,下面的语句:
time1 = time2 * 0.9;
被转化为
time1 = time2.operator*(0.9);
而下面语句却无法执行:
time1 = 0.9 * time2;
解决方式
使用非成员函数实现time1 = 0.9 * time2;
(大多数运算符都可以通过成员或非成员函数来重载)。 非成员函数不是由对象调用的,它使用的所有值(包括对象)都是显式参数。这样,编译器能够将下面的表达式:
time1 = 0.9 * time2;
与下面的非成员函数调用匹配:
time1 = operator*(0.9, time2);
该函数的原型如下:
Time operator*(double m, const Time & t);
但这样做引发了一个新问题:非成员函数不能直接访问类的私有数据。然而,有一类特殊的非成员函数可以访问类的私有成员,它们被称为友元函数。
3种友元
友元函数
-
第一步
创建友元函数的第一步是将其原型放在类声明中,并在原型声明前加上关键字friend
:friend Time operator*(double m, const Time & t);
该原型意味着下面两点:
① 虽然operator*()
函数是在类声明中声明的,但它不是成员函数,因此不能使用成员运算符来调用;
② 虽然operator*()
函数不是成员函数,,但它与成员函数的访问权限相同。 -
第二步
第二步是编写函数定义。因为它不是成员函数,所以不要使用Time::限定符。另外,不要在定义中使用关键字friend,定义应该如下:Time operator*(double m, const Tie & t) { ... }
评论区