关于C++友元的一些思考


友元在C++里面是一个比较重要的东西,对于类里面声明的私有数据与函数,如果在某些应用需求下需要被其他函数调用,这时候就需要使用友元函数。就好像给了一个声明,说某某函数是我这个类的一个好朋友,你们可以大胆地放他进入我的闺房,访问我的数据。

在C++里面,我们定义友元是使用friend 这个关键字。声明友元函数可以有下面四种情况。

  1. class X {  
  2. private:  
  3.   int i;  
  4. public:  
  5.   friend void h();  
  6.   friend class Z;  
  7.   frined void g(X*, int);  
  8.   friend Y::f(X*);  
  9. };  

friend void h(); 声明的友元函数是一个全局函数,这里其实做了两件事,一件事声明一个函数 void h();,另一件事是声明该函数属于X类的一个友元函数。

friend class Z 声明类Z是友元类,即类Z里面所有方法都可以引用A中的私有数据与私有函数。

friend void g(X*, int) 这个是比较常用的方式,跟上面的全局函数是一样的。

要强调的是friend Y::f(X*); 制定在类Y里面的特定函数为友元。这里有一个问题要注意到,就是声明的顺序。在声明友元函数之前必然是要求先声明类Y以及类Y里面的f()方法,不然系统是找不到对应的类。然后由于类Y里面有类X作为参数,也必然需要在声明函数f()之前先有类X的声明。这无疑是一个很大的矛盾。如何解决这个矛盾呢,是有技巧的。

  1. class X;  
  2.    
  3. class Y {  
  4.   void f(X*);  
  5. };  
  6.   
  7. class X {  
  8. private:  
  9.   int i;  
  10. public:  
  11.   friend void h();  
  12.   friend class Z;  
  13.   frined void g(X*, int);  
  14.   friend Y::f(X*);  
  15. };  

如上面代码所示,我们在声明f(X*)之前有了类X的一个声明,这里仅仅是声明,并没有定义。在声明友元之前也有类Y的一个声明,这就圆了场。然而也要注意到,这里有一个细节,f(X*)的参数是一个指针。由于在类Y前面类X只是一个声明,但是对于类X的大小,在扫描到类Y时是未知的,所以只能传入一个指针来解决这个冲突。

相关内容