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

原创 2001年05月04日 13:08:00

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

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


FAQs in section [14]:


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

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

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

TopBottomPrevious sectionNext section ]


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

[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:存取函数的语法不同的变种来使用的话,友元函数就和破坏封装的成员函数一样会破坏封装。换一种说法,类的友元不会破坏封装的壁垒:和类的成员函数一样,它们就是封装的壁垒。

TopBottomPrevious sectionNext 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&)

TopBottomPrevious sectionNext section ]


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

[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对象的访问特权。

TopBottomPrevious sectionNext section ]


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

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

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

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

TopBottomPrevious sectionNext section ]


E-Mail E-mail the author
C++ FAQ LiteTable of contentsSubject indexAbout the author©Download your own copy ]
Revised Apr 8, 2001

C++中如何声明 “友元类” 和 “友元函数”

调试平台:win7 vs2012 win32控制台终端项目 友元(friend) 字面义:顾名思义既然是朋友了,我的东西同样可以给你使用 书面语:将一个类的非公有成员(包括方法和成员变量)的访问权限赋...
  • comwise
  • comwise
  • 2013年11月05日 18:57
  • 2802

关于C++中的友元函数的总结

1.友元函数的简单介绍 1.1为什么要使用友元函数 在实现类之间数据共享时,减少系统开销,提高效率。如果类A中的函数要访问类B中的成员(例如:智能指针类的实现),那么类A中该函数要是类B的友元函数...
  • zhouwei1221q
  • zhouwei1221q
  • 2015年08月24日 16:48
  • 520

c++友元实现操作符重载

运算符重载的本质是一个函数#include using namespace std;class A { private: int m_a; int m_b; friend A ...
  • sjtu_chenchen
  • sjtu_chenchen
  • 2015年08月22日 16:14
  • 1824

c++中友元函数理解与使用。

在学习c++这一块,关于友元函数和友元类,感觉还是不好理解,但是井下心来,理解,需要把我一下几点。 首先讲友元函数。 (1)友元函数: 1)C++中引入友元函数,是为在该类中提供一个对外(除了他...
  • qq_26337701
  • qq_26337701
  • 2017年01月03日 17:09
  • 1377

C++友元函数和友元类的使用基础

友元函数百度百科:       友元函数是指某些虽然不是类成员却能够访问类的所有成员的函数。。类授予它的友元特别的访问权。通常同一个开发者会出于技术和非技术的原因,控制类的友元和成员函数(否则当你想...
  • zgrjkflmkyc
  • zgrjkflmkyc
  • 2013年03月13日 11:27
  • 4830

一个友元类使用误区(C++)

这个问题,我困扰了好一会。决定记录一下
  • qq_33850438
  • qq_33850438
  • 2016年12月09日 21:10
  • 1033

C++中友元类使用场合

在C++中我们可以將函数定义成类的友元函数,这样在函数中就可以访问类的私有成员。与函数相同,类也可以作为另一个类的友元类,在友元类中可以访问另外一个类的所有成员。 声明友元类的方法很简单,只需在类中...
  • Rongbo_J
  • Rongbo_J
  • 2015年04月17日 10:48
  • 3570

友元函数this

关于C++中的友元函数的总结 1.友元函数的简单介绍 1.1为什么要使用友元函数 在实现类之间数据共享时,减少系统开销,提高效率。如果类A中的函数要访问类B中的成员(例如:智能指针类的实...
  • lusic01
  • lusic01
  • 2016年11月21日 10:54
  • 706

C++之模板(友元函数+友元类+静态Static)

友元函数 友元函数分为友元全局函数和友元成员函数。 下面是一个友元全局函数的例子:class Coordinate { friend void printXY(Coordinate &c...
  • u013486414
  • u013486414
  • 2017年03月05日 20:57
  • 465

C++ - 类模板(class template)友元(friend) 的 全部六种形式 及 代码

类模板(class template)友元(friend) 的 全部六种形式 及 代码   版权所有, 禁止转载, 如有需要, 请站内联系; 本文地址: http://blog.csdn.net/ca...
  • u012515223
  • u012515223
  • 2013年11月24日 09:31
  • 10102
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++ FAQ Lite[14]--友元(更新)
举报原因:
原因补充:

(最多只允许输入30个字)