分享
 
 
 

C++ FAQ Lite[14]--友元(更新)

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

[14] 友元

(Part of C++ FAQ Lite, ]Copyright © 1991-2001, Marshall Cline, cline@parashift.com)

简体中文版翻译:申旻nicrosoft@sunistudio.com东日制作室东日文档

FAQs in section [14]:

][14.1] 什么是友元(friend])?

][14.2] 友元破坏了封装吗?

][14.3] 使用友元函数的优缺点是什么?

][14.4] “友元关系既不继承,也不传递”是什么意思?

][14.5] 我的类应该使用成员函数还是友元函数?

[14.1] 什么是友元(friend)?

允许另一个类或函数访问你的类的东西。

友元可以是函数或者是其他的类。类授给它的友元特别的访问权。通常同一个开发者会在技术和非技术上控制类的友元和成员函数(否则当你想更新你的类时,还要征得其它部分的拥有者的同意)。

[ Top | Bottom | Previous section | Next section ]

[14.2] 友元破坏了封装吗?

[Recently made a bit more emphatic (on 4/01). ]Click here to go to the next FAQ in the "chain" of recent changes.]

如果被适当的使用,实际上可以增强封装。

当一个类的两部分会有不同数量的实例或者不同的生命周期时,你经常需要将一个类分割成两部分。在这些情况下,两部分通常需要直接存取彼此的数据(这两部分原来在同一个类中,所以你不必增加直接存取一个数据结构的代码;你只要将代码改为两个类就行了)。实现这种情况的最安全途径就是使这两部分成为彼此的友元。

如果你象刚才所描述的那样使用友元,就可以使私有的(private)保持私有。不理解这些的人在以上这种情形下还天真的想避免使用友元,他们要么使用公有的(public)数据(罕见!),要么通过公有的 get()和set()成员函数使两部分可以访问数据。而他们实际上破坏了封装。只有当在类外(从用户的角度)看待私有数据仍“有意义”时,为私有数据设置公有的get()和set()成员函数才是合理的。在许多情况下,这些 get()/set()成员函数和公有数据一样差劲:它们仅仅隐藏了私有数据的名称,而没有隐藏私有数据本身。

同样,如果你将友元函数当做一种类的public:存取函数的语法不同的变种来使用的话,友元函数就和破坏封装的成员函数一样会破坏封装。换一种说法,类的友元不会破坏封装的壁垒:和类的成员函数一样,它们就是封装的壁垒。

[ Top | Bottom | Previous section | Next section ]

[14.3] 使用友元函数的优缺点是什么?

友元函数在接口设计选择上提供了一定程度的自由。

成员函数和友元函数具有同等的特权(100% 的)。主要的不同在于友元函数象f(x)这样调用,而成员函数象 x.f()这样调用。因此,可以在成员函数(x.f())和友元函数(f(x))之间选择的能力允许设计者选择他所认为更具可读性的语法来降低维护成本。

友元函数主要缺点是需要额外的代码来支持动态绑定时。要得到虚友元(virtual friend)的效果,友元函数应该调用一个隐藏的(通常是 protected:)成员函数。这称为]虚友元函数用法(Virtual Friend Function Idiom)。例如:

class Base {

public:

friend void f(Base& b);

// ...

protected:

virtual void do_f();

// ...

};

inline void f(Base& b)

{

b.do_f();

}

class Derived : public Base {

public:

// ...

protected:

virtual void do_f(); // "覆盖" f(Base& b)的行为

// ...

};

void userCode(Base& b)

{

f(b);

}

在userCode(Base&)中的f(b)语句将调用虚拟的 b.do_f()。这意味着如果b实际是一个派生类的对象,那么Derived::do_f()将获得控制权。注意派生类覆盖的是保护的虚(protected: virtual)成员函数 do_f(); 而不是它友元函数f(Base&)。

[ Top | Bottom | Previous section | Next section ]

[14.4] “友元关系既不继承,也不传递”是什么意思?

[Recently added the "not reciprocal" item thanks to Karel Roose (on 4/01). ]Click here to go to the next FAQ in the "chain" of recent changes.]

仅仅因为我承认对你的友情,允许你访问我,并不自动地允许你的孩子访问我,并不自动地允许你的朋友访问我,并不自动地允许我访问你。

我不必信任我朋友的孩子。友元的特权不被继承。友元的派生类不一定是友元。如果 Fred 类声明Base类是友元,那么Base类的派生类不会自动地被赋予对于Fred的对象的访问特权。

我不必信任我朋友的朋友。友元的特权不被传递。友元的友元不一定是友元。如果Fred类声明Wilma类是友元,并且Wilma类声明Betty类是友元,那么Betty类不会自动地被赋予对于Fred的对象的访问特权。

你不必仅仅因为我声称你是我的朋友就信任我。友元的特权不是自反的。如果Fred类声明Wilma类是友元,则Wilma对象拥有访问Fred对象的特权,但Fred对象不会自动地拥有对Wilma对象的访问特权。

[ Top | Bottom | Previous section | Next section ]

[14.5] 我的类应该使用成员函数还是友元函数?

尽量使用成员函数,不得已时使用友元。

有时在语法上,友元更好(例如,Fred类中,友元函数允许Fred参数作为第二个参数,而成员函数必须是第一个)。另一个好的用法是二元中缀运算符。例如,如果你想允许aFloat + aComplex 的话,aComplex + aComplex 应该被定义为友元而不是成员函数。(成员函数不允许提升左边的参数,因为那样会改变成员函数调用对象的类)。

在其他情况下,首选成员函数。

[ Top | Bottom | Previous section | Next section ]

E-mail the author

[ C++ FAQ Lite | Table of contents | Subject index | ]About the author | | ]Download your own copy ]

Revised Apr 8, 2001

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有