from : http://www.cnblogs.com/accepted/archive/2010/09/04/1818173.html
在封装中C++类数据成员大多情况是private属性;但是如果接口采用多参数实现肯定影响程序效率;然而这时候如果外界需要频繁访问这些私有成员,就不得不需要一个既安全又理想的“后门”——友元关系;
C++中提供三种友元关系的实现方式,友元函数、友元成员函数、友元类。
友元函数:既将一个普通的函数在一个类中说明为一个friend属性;其定义(大多数会访问该类的成员)应在类后;
友元成员函数:既然是成员函数,那么肯定这个函数属于某个类,对了就是因为这个函数是另外一个类的成员函数,有时候因为我们想用一个类通过一个接口去访问另外一个类的信息,然而这个信息只能是被它授权的类才能访问;那么也需要用friend去实现;这个概念只是在声明的时候稍有变化;
友元类:友元类声明会将整个类说明成为另一个类的友元关系;和之前两种的区别是集体和个人的区别;友元类的所有成员函数都可以是另一个类的友元函数;
值得注意的是友元关系是单向的,有点像我们恋爱中出现的单相思 O(∩_∩)O,单向关系就是说如果A被说明成B的友元关系,那么只能说A是B的友元,并不代表B是A的友元;其次在多数情况下友元关系的函数都会访问它被说明中类的成员,这时候应该将函数定义在类的后面;
下面给一个简单的例程代码;
2
3 using namespace std;
4
5 class B;
6
7 class A{
8 private :
9 int x;
10 public :
11 A();
12 void display(B & );
13 };
14
15 class C;
16
17 class B{
18 private :
19 int y;
20 int z;
21 public :
22 B();
23 B( int , int );
24 friend void A::display(B & ); // 友元成员函数
25 friend void display(B & ); // 友元函数
26 friend class C; // 友元类
27 };
28
29 class C{
30 private :
31 int sum;
32 void calc(B & );
33 public :
34 C();
35 void display(B & );
36 };
37
38 // 必须在友元关系的类后进行定义
39 void display(B & v) // 友元函数
40 {
41 cout << v.y << " " << v.z << endl;
42 }
43
44 A::A()
45 {
46 this -> x = 0 ;
47 }
48
49 void A::display(B & v) // 友元成员函数
50 {
51 this -> x = v.y + v.z;
52 cout << this -> x << endl;
53 }
54
55 B::B()
56 {
57 this -> y = 0 ;
58 this -> z = 0 ;
59 }
60
61 B::B( int y, int z)
62 {
63 this -> y = y;
64 this -> z = z;
65 }
66
67 C::C()
68 {
69 sum = 0 ;
70 }
71
72 void C::display(B & v)
73 {
74 this -> calc(v);
75 cout << sum << " = " << v.y << " + " << v.z << endl;
76 }
77
78 void C::calc(B & v)
79 {
80 sum = v.y + v.z;
81 }
82
83 int main()
84 {
85 A a;
86 B b( 2 , 3 );
87 display(b);
88 a.display(b);
89 C c;
90 c.display(b);
91
92 return 0 ;
93 }
94
=======================什么是友元类=======================
当一个类B成为了另外一个类A的“朋友”时,那么类A的私有和保护的数据成员就可以被类B访问。我们就把类B叫做类A的友元。
=======================友元类能做什么=======================
友元类可以通过自己的方法来访问把它当做朋友的那个类的所有成员。但是我们应该注意的是,我们把类B设置成了类A的友元类,但是这并不会是类A成为类B的友元。说白了就是:甲愿意把甲的秘密告诉乙,但是乙不见得愿意把乙自己的秘密告诉甲。
=======================友元类的声明方法和其用法=======================
声明友元类的方法其实很简单,只要我们在类A的成员列表中写下如下语句:
friend
class
B;
|
这样一来,类B就被声明成了类A的友元。注意,类B虽然是类A的友元,但是两者之间不存在继承关系。这也就是说,友元类和原来那个类之间并没有什么继承关系,也不存在包含或者是被包含的关系,友元类和我上一篇博文《谈谈:C++类的“包含”机制》中的包含是完全不一样的!
=======================友元类的一个具体例子=======================
在这里,我们引用一个我从网上收集到的例子来说明友元类的作用:假设我们要设计一个模拟电视机和遥控器的程序。大家都之道,遥控机类和电视机类是不相包含的,而且,遥控器可以操作电视机,但是电视机无法操作遥控器,这就比较符合友元的特性了。即我们把遥控器类说明成电视机类的友元。下面是这个例子的具体代码:
#include <iostream>
using
namespace
std;
class
TV
{
public
:
friend
class
Tele;
TV():on_off(off),volume(20),channel(3),mode(tv){}
private
:
enum
{on,off};
enum
{tv,av};
enum
{minve,maxve=100};
enum
{mincl,maxcl=60};
bool
on_off;
int
volume;
int
channel;
int
mode;
};
class
Tele
{
public
:
void
OnOFF(TV&t){t.on_off=(t.on_off==t.on)?t.off:t.on;}
void
SetMode(TV&t){t.mode=(t.mode==t.tv)?t.av:t.tv;}
bool
VolumeUp(TV&t);
bool
VolumeDown(TV&t);
bool
ChannelUp(TV&t);
bool
ChannelDown(TV&t);
void
show(TV&t)
const
;
};
bool
Tele::VolumeUp(TV&t)
{
if
(t.volume<t.maxve)
{
t.volume++;
return
true
;
}
else
{
return
false
;
}
}
bool
Tele::VolumeDown(TV&t)
{
if
(t.volume>t.minve)
{
t.volume--;
return
true
;
}
else
{
return
false
;
}
}
|