友元

友元是对类中成员的另一种形式的访问权限,友元可以与类的成员函数一样访问类中的成员。友元有三种:

  1. 友元函数。
  2. 友元类。
  3. 友元成员函数。

前面Time类中重载的+操作符是以成员函数形式定义的,其调用时会默认将调用实例作为左操作数传入。但是如果当调用实例出现在操作符右侧,那么就会出现错误。使用友元可以解决这种结合律的问题。例如可以创建以下友元函数。

class Time {
    public:
        friend Time operator+(const Time& t, const Time& t2);
        friend ostream& operator<<(ostream& os, const Time& t); // 可以支持链式向cout输出的操作
}

友元函数放置在类声明中,使用friend关键字声明。但是友元函数在实现时,因为其不是类的成员,所以不需要使用::限定,直接实现函数即可(去掉friend关键字)。

友元类的声明比较简单,只需要在类的声明中添加friend class 友元类名;即可让友元类访问本类的全部成员。但是在大部分情况下并不需要让整个类成为本类的友元,所以就出现了友元成员函数,这允许让另一个类中的某个成员函数成为本类的友元,访问本类的全部成员。友元成员函数的声明格式为friend 友元成员函数返回值类型 所属类名称::成员函数名(参数列表);。例如:

class TV; // 由于Remote使用了TV类,编译器需要确定TV类的存在,所以使用前向声明
class class Remote {
    public:
        void set_channel(TV& tv, int ch);
}
class TV {
    public:
        friend void Remote::set_channel(TV& tv, int ch);
}