什么时候应该用到友元类

什么时候希望一个类成为另一个类的友元类呢?我们来看一个例子:

假定需要编写一个模拟电视机和遥控器的简单程序。决定定义一个Tv类和一个Remote类,来分别表示电视机和遥控器。很明显,这两个类之间应当存在某种关系,但是什么样的关系呢?遥控器并非电视机,反之亦然,所以公有继承的is-a关系并不适用。遥控器也非电视机的一部分,反之亦然,因此包含或私有继承和保护继承的has-a关系也不适用。事实上,遥控器可以改变电视机的状态,这表明应将Remote类作为Tv类的一个友元。

在 C++ 中,友元(friend)是一种机制,允许非成员函数、其他的成员函数访问一个的私有(private)和保护(protected)成员。友元有三种实现方式:全局函数友元友元、成员函数友元[^5]。 ### 全局函数友元 将一个全局函数声明为友元,该函数可以访问的私有和保护成员。声明一个友元函数,只需在定义中声明该函数并且前面加一个关键字 `friend`。虽然友元函数在的声明中声明,但它不是成员函数,因此不能使用成员运算符来调用;不过它与成员函数的访问权限相同。例如重载 `<<` 运算符时常用友元函数: ```cpp #include <iostream> class Time { private: int hours; int minutes; public: Time(int h = 0, int m = 0) : hours(h), minutes(m) {} friend std::ostream & operator<<(std::ostream & os, const Time & t); }; std::ostream & operator<<(std::ostream & os, const Time & t) { os << t.hours << " hours, " << t.minutes << " minutes"; return os; } int main() { Time t(2, 30); std::cout << t << std::endl; return 0; } ``` ### 友元 将一个(称为友元)声明为另一个友元,这样友元的所有成员函数都可以访问该的私有和保护成员。示例如下: ```cpp class Date; // Date的声明 class Time { // 友元 friend class Date; public: Time(int hour = 0, int minute = 0, int second = 0) : _hour(hour), _minute(minute), _second(second) {} private: int _hour; int _minute; int _second; }; class Date { public: void SetDateTime(int hour, int minute, int second) { _t._hour = hour; _t._minute = minute; _t._second = second; } private: int _year; int _month; int _day; Time _t; }; ``` ### 成员函数友元 将另一个的成员函数声明为友元,这样只有该成员函数可以访问的私有和保护成员。 ### 模板中的友元函数 一个可以将另一个模板的每个实例都声明为自己的友元(即通用模板),或者限定特定的实例为友元(即特定模板)。示例如下: ```cpp // 前置声明,在将模板的一个特定实例声明为友元时要用到 template<typename T> class Pal; class C { // C为一个普通的非模板 friend class Pal<C>; // pal本身是模板,用C实例化后,pal的型是C, // C型的pal又成为了非模板C的友元 // Pal2的所有实例都是C的友元;这种情况无须前置声明 template<typename T> friend class Pal2; }; ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值