在这章中,我们一直保持你的私人数据传的美德。然而,你可能偶尔会发现的情况下,你会发现你的类和函数,需要非常密切的工作。例如,你可能有一个类存储数据,和一个函数(或另一类),数据显示在屏幕上。虽然类存储和显示的代码已经分离更容易维护,显示代码确实是密切相关的存储类的细节。因此,没有太多的显示代码隐藏存储类细节增益。
在这种情况下,有两个选项:
1)有显示代码使用公开曝光功能的存储类。然而,这有几个潜在的负面影响。首先,这些公共成员函数必须定义,这需要时间,而且可以弄乱的存储类的接口。第二,存储类可能暴露的功能显示的代码,它并不真的想让别人。有没有办法说“这个函数是用来由显示类”。
2)或者,使用友元类和友元函数,你可以给你的显示代码访问的存储类的私人细节。这让显示代码直接访问所有的存储类的私有成员和函数!在本课中,我们将采取仔细看看这是怎么做的。
友元函数
一个朋友函数可以访问类的私有成员是类的成员。在所有其他方面,朋友的功能就像一个正常的功能。一个朋友的功能可能会或可能不会是另一个类的成员。声明友元函数,在你想成为该类的一个朋友的函数原型前简单地使用朋友关键词。不管你申报的朋友函数在类的私有或公共部门的事。
这是使用友元函数的一个例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
class
Accumulator { private : int
m_nValue; public : Accumulator()
{ m_nValue = 0; } void
Add( int
nValue) { m_nValue += nValue; } //
Make the Reset() function a friend of this class friend
void
Reset(Accumulator &cAccumulator); }; //
Reset() is now a friend of the Accumulator class void
Reset(Accumulator &cAccumulator) { //
And can access the private data of Accumulator objects cAccumulator.m_nValue
= 0; } |
在这个例子中,我们已经声明了一个函数名为reset()以类蓄电池的对象,并设置为0 m_nvalue价值。因为reset()不是蓄能器类的一个成员,通常reset()不能访问私有成员的蓄电池。然而,由于蓄电池已明确宣布这reset()函数是类的一个朋友,这个reset()函数给出了蓄能器的私有成员的访问。
请注意,我们必须通过蓄能器对象reset()。这是因为reset()不是一个成员函数。它没有这个指针,也不会有一个蓄能器对象的工作,除非得到一个。
虽然这个例子很做作,这里的另一个例子就是一些你会看到在不久的将来再次接近了许多,当我们谈论操作符重载:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
class
Value { private : int
m_nValue; public : Value( int
nValue) { m_nValue = nValue; } friend
bool
IsEqual( const
Value &cValue1, const
Value &cValue2); }; bool
IsEqual( const
Value &cValue1, const
Value &cValue2) { return
(cValue1.m_nValue == cValue2.m_nValue); } |