数学建模社区-数学中国

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

作者: lckboy    时间: 2004-6-4 11:56
标题: C++ 友元(friend)
  <b>问题的提出</FONT>
( G- O5 Q8 T1 N</b></FONT>
# N7 G/ S: k( |( K8 u, s6 j( ]  我们已知道类具有封装和信息隐藏的特性。只有类的成员函数才能访问类的私有成员,程序中的其他函数是无法访问私有成员的。非成员函数可以访问类中的公有成员,但是如果将数据成员都定义为公有的,这又破坏了隐藏的特性。另外,应该看到在某些情况下,特别是在对某些成员函数多次调用时,由于参数传递,类型检查和安全性检查等都需要时间开销,而影响程序的运行效率。</FONT>4 L$ G4 ^& r9 J- p& e: P
</FONT>
4 I& @3 |. [3 K: l6 B! b  为了解决上述问题,提出一种使用友元的方案。友元是一种定义在类外部的普通函数,但它需要在类体内进行说明,为了与该类的成员函数加以区别,在说明时前面加以关键字friend。友元不是成员函数,但是它可以访问类中的私有成员。友元的作用在于提高程序的运行效率,但是,它破坏了类的封装性和隐藏性,使得非成员函数可以访问类的私有成员。</FONT>
2 A! o. G5 w: @+ ]( G, V5 S( a</FONT>4 K3 z8 d: u7 M' u( l
  友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元类。</FONT>
( l6 M8 U+ l3 R: A</FONT>7 f0 F. U4 m' M
  <b>友元函数</FONT>
7 U) z. T; a! {4 t/ Q</b></FONT>& B* t2 Y4 M# Y! g2 \
  友元函数的特点是能够访问类中的私有成员的非成员函数。友元函数从语法上看,它与普通函数一样,即在定义上和调用上与普通函数一样。下面举一例子说明友元函数的应用。</FONT>
4 n- E6 ?! y& w) l) H2 `</FONT>! M; s7 ]. L6 \6 p4 {( D
  #include <IOSTREAM.H></FONT>/ p; N& C' p# I/ H( e
  #include <MATH.H></FONT>
$ W# u" \8 g# M% U6 Y</FONT>
  d  T4 t4 s+ w# Z. d3 q  class Point</FONT>
: d# i: Z5 l$ P$ V  {</FONT>
0 |% U, \6 x! f- P1 f  public:</FONT>
+ r& V' a, k, b, d, o7 L    Point(double xx, double yy) { x=xx; y=yy; }</FONT>
! `% Q/ {+ T$ ^  ~( o: D    void Getxy();</FONT>
0 `9 S% e. C! S& D3 l7 ^    friend double Distance(Point &amp;a, Point &amp;b);</FONT>
7 L1 C0 s# ^- v* c! m  private:</FONT>. f5 o6 I/ G# E% E! N9 r3 v
    double x, y;</FONT>& x5 ^, ]: a: u2 l: m
  };</FONT>
- a* \, ]# H3 a6 }/ K/ C  l2 H</FONT>
, g5 \  t6 i2 v& K% P, N  j# [/ @  void Point::Getxy()</FONT>& y% e+ O  P" C& T
  {</FONT>
& e8 ?/ }6 `! H  ^. {8 w  cout&lt;&lt;"("&lt;<X<<","<<Y<<")"<<ENDL;< FONT>% L: W; ?$ |+ x- W* O( k6 V* Z
  }</FONT>! @0 b" U! Q3 s. |0 S+ i
</FONT>/ ^0 v/ i  ]$ m; `3 [) I8 m% ?: s: y4 b
  double Distance(Point &amp;a, Point &amp;b)</FONT>7 a3 U4 v& J" ]  \6 t
  {</FONT>* \7 G$ L- R: I/ {6 U/ ?* c4 g$ W7 E
  double dx = a.x - b.x;</FONT>
- Z5 T2 f9 q% L* _+ A- n, d: q0 Z  double dy = a.y - b.y;</FONT>
' L7 v8 L5 a* E! a& V$ N  return sqrt(dx*dx+dy*dy);</FONT>
$ G1 c- f8 `3 b0 A8 P: _  q# h  }</FONT>  `% s( f% B" F3 y# M* H! q2 i
</FONT>
0 [' g( T% x' u  R1 X  void main()</FONT>1 Q  \0 ]8 f1 T
  {</FONT>
$ m0 f' ~. Y4 M7 B+ y" `, _2 ]4 ]  Point p1(3.0, 4.0), p2(6.0, 8.0);</FONT>4 J3 z. F" L- W+ ]. Q( f# M
  p1.Getxy();</FONT>
1 p* ]2 l, e- ~( ^) ~  p2.Getxy();</FONT>
# x8 W9 i! @+ @! t  double d = Distance(p1, p2);</FONT>
  I) H0 @- `9 t0 d7 e  G2 [  cout&lt;&lt;"Distance is"&lt;<D<<ENDL;< FONT>% R+ Y$ T" s' m) L9 V
  }</FONT>* W1 D, l1 j; N. Z) Q1 V0 Q3 t
</FONT>
. u. [, @2 S2 T. o, o2 V  说明:在该程序中的Point类中说明了一个友元函数Distance(),它在说明时前边加friend关键字,标识它不是成员函数,而是友元函数。它的定义方法与普通函数定义一样,而不同于成员函数的定义,因为它不需要指出所属的类。但是,它可以引用类中的私有成员,函数体中a.x,b.x,a.y,b.y都是类的私有成员,它们是通过对象引用的。在调用友元函数时,也是同普通函数的调用一样,不要像成员函数那样调用。本例中,p1.Getxy()和p2.Getxy()这是成员函数的调用,要用对象来表示。而Distance(p1, p2)是友元函数的调用,它直接调用,不需要对象表示,它的参数是对象。(该程序的功能是已知两点坐标,求出两点的距离。)</FONT>
" l! ^0 y2 c& |3 D1 O9 h: }</FONT>
5 Z& V: Z" z  u4 C$ q$ e  <b>友元类</b></FONT>/ }( H3 k' _' y. l, z( n" `
</FONT>
! p+ ?7 s0 O" v4 W' j  友元除了前面讲过的函数以外,友元还可以是类,即一个类可以作另一个类的友元。当一个类作为另一个类的友元时,这就意味着这个类的所有成员函数都是另一个类的友元函数。</FONT>8 Y# O# L( P+ s1 k8 t) k
</FONT>
作者: ilikenba    时间: 2004-6-4 23:30
不错!回忆起来了!




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