C++_友元函數總結(轉)


 原文地址: http://blog.csdn.net/insistgogo/article/details/6608672
 
1、為什么要引入友元函數:在實現類之間數據共享時,減少系統開銷,提高效率

      具體來說:為了使其他類的成員函數直接訪問類的私有變量

      即:允許外面的類或函數去訪問類的私有變量和保護變量,從而使兩個類共享同一函數

      優點:能夠提高效率,表達簡單、清晰

      缺點:友元函數破環了封裝機制,盡量不使用成員函數,除非不得已的情況下才使用友元函數。

2、什么時候使用友元函數:

      1)運算符重載的某些場合需要使用友元。

      2)兩個類要共享數據的時候

3、怎么使用友元函數:

友元函數的參數:

       因為友元函數沒有this指針,則參數要有三種情況:

       1、  要訪問非static成員時,需要對象做參數;--常用(友元函數常含有參數)

       2、  要訪問static成員或全局變量時,則不需要對象做參數

       3、  如果做參數的對象是全局對象,則不需要對象做參數

友元函數的位置:

       因為友元函數是類外的函數,所以它的聲明可以放在類的私有段或公有段且沒有區別。

友元函數的調用:

       可以直接調用友元函數,不需要通過對象或指針

友元函數的分類:

根據這個函數的來源不同,可以分為三種方法:

1、普通函數友元函數:

       a) 目的:使普通函數能夠訪問類的友元

       b) 語法:聲明位置:公有私有均可,常寫為公有

                        聲明: friend + 普通函數聲明

                        實現位置:可以在類外或類中

                        實現代碼:與普通函數相同(不加不用friend和類::

                        調用:類似普通函數,直接調用

       c) 代碼:        

 
 1 class INTEGER  
 2 {    
 3 private:  
 4     int num;  
 5 public:  
 6     friend void Print(const INTEGER& obj);//聲明友元函數  
 7 };  
 8 void Print(const INTEGER& obj)//不使用friend和類::  
 9 {  
10     //函數體  
11 }  
12 void main()  
13 {  
14     INTEGER obj;  
15     Print(obj);//直接調用  
16 }  

 

2、類Y的所有成員函數都為類X友元函數—友元類

      a)目的:使用單個聲明使Y類的所有函數成為類X的友元

                        它提供一種類之間合作的一種方式,使類Y的對象可以具有類X和類Y的功能

                        具體來說:

                                前提:A是B的友元(=》A中成員函數可以訪問B中有所有成員,包括私有成員和公有成員--老忘)

                                    則:在A中,借助類B,可以直接使用~B . 私有變量~的形式訪問私有變量

      b)語法:聲明位置:公有私有均可,常寫為私有(把類看成一個變量)

                        聲明: friend + 類名---不是對象啊

                        調用:

      c)代碼:

 
 1 class girl;  
 2   
 3 class boy  
 4 {    
 5 private:  
 6     char *name;    
 7     int age;    
 8 public:    
 9     boy();  
10     void disp(girl &);     
11 };    
12   
13 void boy::disp(girl &x)
14  //函數disp()為類boy的成員函數,也是類girl的友元函數   
15 {   
16     cout<<"boy's name is:"<<name<<",age:"<<age<<endl;
17 //正常情況,boy的成員函數disp中直接訪問boy的私有變量  
18     cout<<"girl's name is:"<<x.name<<",age:"<<x.age<<endl;   
19     /*借助友元,在boy的成員函數disp中,借助girl的對象,直接訪girl的私有變量  
20       正常情況下,只允許在girl的成員函數中訪問girl的私有變量  */
21 }  
22   
23 class girl  
24 {    
25 private26     char *name;    
27     int age;    
28     friend boy;   //聲明類boy是類girl的友元    
29 public:    
30     girl();     
31 };    
32 void main()    
33 {     
34     boy b;    
35     girl g;    
36     b.disp(g);
37  //b調用自己的成員函數,但是以g為參數,友元機制體現在函數disp中  
38 }  

 

 

3、類Y的一個成員函數為類X的友元函數

      a)目的:使類Y的一個成員函數成為類X的友元

             具體而言:而在類Y的這個成員函數中,借助參數X,可以直接以X。私有變量的形式訪問私有變量

      b)語法:聲明位置:聲明在公有中 (本身為函數)

                        聲明:friend + 成員函數的聲明

                        調用:先定義Y的對象y---使用y調用自己的成員函數---自己的成員函數中使用了友元機制

      c)代碼: 

 1 class girl;   
 2 class boy  
 3 {    
 4 private:  
 5     char *name;    
 6     int age;    
 7 public:    
 8     boy();  
 9     void disp(girl &);       
10 };     
11    
12 class girl  
13 {  
14 private:  
15     char *name;    
16     int age;    
17 public:    
18     girl(char *N,int A);    
19     friend void boy::disp(girl &); 
20 //聲明類boy的成員函數disp()為類girl的友元函數    
21 };    
22    
23 void boy::disp(girl &x)    
24 {     
25     cout<<"boy's name is:"<<name<<",age:"<<age<<endl; 
26  //訪問自己(boy)的對象成員,直接訪問自己的私有變量    
27     cout<<"girl's name is:"<<x.name<<",age:"<<x.age<<endl;    
28  //借助友元,在boy的成員函數disp中,借助girl的對象,直接訪問girl的私有變量  
29     //正常情況下,只允許在girl的成員函數中訪問girl的私有變量    
30 }    
31 void main()    
32 {     
33     boy b();    
34     girl g();    
35     b.disp(g);  }  

 

4、在模板類中使用友元operator<<(對<<運算符的重載)

    a)使用方法:

在模板類中聲明:

[cpp]  view plain copy
 
  1. friend ostream& operator<< <>(ostream& cout,const MGraph<VexType,ArcType>& G);  

在模板類中定義:

[cpp]  view plain copy
 
  1. template<class VexType,class ArcType>  
  2. ostream& operator<<(ostream& cout,const MGraph<VexType,ArcType>& G)  
  3. {  
  4.     //函數定義  
  5. }  

    b)注意:

把函數聲明非模板函數:

[cpp]  view plain copy
 
  1. friend ostream& operator<< (ostream& cout,const MGraph& G);  

把函數聲明為模板函數:

[cpp]  view plain copy
 
  1. friend ostream& operator<< <>(ostream& cout,const MGraph<VexType,ArcType>& G);  

或:

[cpp]  view plain copy
 
  1. friend ostream& operator<< <VexType,ArcType>(ostream& cout,const MGraph<VexType,ArcType>& G);  

說明:
 在函數聲明中加入operator<< <>:是將operator<<函數定義為函數模板,將函數模板申明為類模板的友員時,是一對一綁定的
 實際的聲明函數:這里模板參數可以省略,但是尖括號不可以省略

[cpp]  view plain copy
 
  1. friend ostream& operator<< <VexType,ArcType>(ostream& cout,const MGraph<VexType,ArcType>& G);  

5、友元函數和類的成員函數的區別:成員函數有this指針,而友元函數沒有this指針。

6、記憶:A是B的友元《=》A是B的朋友《=》借助B的對象,在A中可以直接 通過B。成員變量(可以是公有,也可以為私有變量) 的方式訪問B 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM