数学建模社区-数学中国

标题: C++ 友元(friend) [打印本页]

作者: lckboy    时间: 2004-6-4 11:56
标题: C++ 友元(friend)
  <b>问题的提出</FONT>3 o8 b+ C, c  S. u
</b></FONT>
0 K# M. d) r2 c5 v  我们已知道类具有封装和信息隐藏的特性。只有类的成员函数才能访问类的私有成员,程序中的其他函数是无法访问私有成员的。非成员函数可以访问类中的公有成员,但是如果将数据成员都定义为公有的,这又破坏了隐藏的特性。另外,应该看到在某些情况下,特别是在对某些成员函数多次调用时,由于参数传递,类型检查和安全性检查等都需要时间开销,而影响程序的运行效率。</FONT>- X6 R% p7 s) P8 P
</FONT>* t. H' M& }; I- ^: l8 G% \! o
  为了解决上述问题,提出一种使用友元的方案。友元是一种定义在类外部的普通函数,但它需要在类体内进行说明,为了与该类的成员函数加以区别,在说明时前面加以关键字friend。友元不是成员函数,但是它可以访问类中的私有成员。友元的作用在于提高程序的运行效率,但是,它破坏了类的封装性和隐藏性,使得非成员函数可以访问类的私有成员。</FONT>2 q; ~+ @, w" T' {8 a9 h8 L, @
</FONT>
2 o% j6 f5 m# @; H  友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元类。</FONT>" \% ?2 `  y1 k* h
</FONT>
8 A# d9 ?- u( l: b) Y  ^  <b>友元函数</FONT>/ c2 W! ^. J2 x. _- B$ y9 c
</b></FONT>! o6 u: f* N. i: K- M) S3 h
  友元函数的特点是能够访问类中的私有成员的非成员函数。友元函数从语法上看,它与普通函数一样,即在定义上和调用上与普通函数一样。下面举一例子说明友元函数的应用。</FONT>9 T2 p  }) @& g% }& w6 Q
</FONT>
" [! U' s( @3 b, F  #include <IOSTREAM.H></FONT>
) g9 [5 X1 F: F# y  {/ \  #include <MATH.H></FONT>  L, }- @# Z  y5 n. ]) M
</FONT>9 g$ V; r7 B% u2 s2 [0 @
  class Point</FONT>' X: E. W  D9 g. f; |3 N0 Q' n. {
  {</FONT>
% I- l+ W9 r) `& m* b" k8 a2 a6 C  public:</FONT>
$ Z2 T" _' o; `' c" n! S& {    Point(double xx, double yy) { x=xx; y=yy; }</FONT>
% e; L& o, W& Z% y, ]    void Getxy();</FONT>
' m+ W' b; J9 w# B) ?+ N    friend double Distance(Point &amp;a, Point &amp;b);</FONT>
% h$ Y6 ?4 D. v6 v; _2 @# n  private:</FONT>, I( ~: W+ C; i! A
    double x, y;</FONT>: H& n" G4 l2 ~# D, k, N
  };</FONT>9 U) B1 B4 n* A7 b2 F: t
</FONT>
4 I. Q% }9 i- a- m# j  void Point::Getxy()</FONT>
/ L/ _8 {3 w6 x( o0 K  {</FONT>
; u$ s9 w' V" N' f6 o6 \+ ~. d4 C  cout&lt;&lt;"("&lt;<X<<","<<Y<<")"<<ENDL;< FONT>6 T" ]2 n0 @# h. {$ L! P7 Z
  }</FONT>
1 o4 t8 q% o4 B: s  O' P0 w; P</FONT>
2 y/ ~' u. R8 I0 ^& |! c" m/ W  double Distance(Point &amp;a, Point &amp;b)</FONT>
3 {; P, r8 P! [  q2 f5 R  {</FONT>
) O7 w4 }* m9 [& e2 L) F  double dx = a.x - b.x;</FONT>! s- c( _3 `" g
  double dy = a.y - b.y;</FONT>
( e" R1 }1 U$ f, m. r  return sqrt(dx*dx+dy*dy);</FONT>0 f* ?" R! P, [6 }5 \
  }</FONT>& j1 U8 M" \! z6 `7 C
</FONT>
7 b6 v& N. N2 w' J7 i$ h  void main()</FONT>  R7 J. i. r( c
  {</FONT>& b3 _+ w- ?& }3 H1 \* T. W
  Point p1(3.0, 4.0), p2(6.0, 8.0);</FONT>
  \1 _( z0 ?9 K" T; E+ z9 `* y  p1.Getxy();</FONT>
) D8 O: L  X  S6 t  h0 X  p2.Getxy();</FONT>
" e1 c" R1 Z5 A+ a5 t+ U  double d = Distance(p1, p2);</FONT>7 P( n0 s% j& Q8 d
  cout&lt;&lt;"Distance is"&lt;<D<<ENDL;< FONT>
  G% G2 z! W2 {& ?, P  }</FONT>
, r# V. D7 u. n</FONT>
8 N) F+ b* A% \+ k: p! z* s  说明:在该程序中的Point类中说明了一个友元函数Distance(),它在说明时前边加friend关键字,标识它不是成员函数,而是友元函数。它的定义方法与普通函数定义一样,而不同于成员函数的定义,因为它不需要指出所属的类。但是,它可以引用类中的私有成员,函数体中a.x,b.x,a.y,b.y都是类的私有成员,它们是通过对象引用的。在调用友元函数时,也是同普通函数的调用一样,不要像成员函数那样调用。本例中,p1.Getxy()和p2.Getxy()这是成员函数的调用,要用对象来表示。而Distance(p1, p2)是友元函数的调用,它直接调用,不需要对象表示,它的参数是对象。(该程序的功能是已知两点坐标,求出两点的距离。)</FONT>
* F* C- L. Y$ K( E# Z5 ?5 M</FONT>+ J2 Z: \7 c) [0 J3 a
  <b>友元类</b></FONT>
5 `& d) U" b, s, H</FONT>
. G, {# D& w  }: ^2 @. G  友元除了前面讲过的函数以外,友元还可以是类,即一个类可以作另一个类的友元。当一个类作为另一个类的友元时,这就意味着这个类的所有成员函数都是另一个类的友元函数。</FONT>
" S3 o" V# t4 I* v3 a  M</FONT>
作者: ilikenba    时间: 2004-6-4 23:30
不错!回忆起来了!




欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5