C++中的友元函數的總結

1爲何要使用友元函數
在實現類之間數據共享時,減小系統開銷,提升效率。若是類A中的函數要訪問類B中的成員(例如:智能指針類的實現),那麼類A中該函數要是類B的友元函數。具體說:爲了
使其餘類的成員函數直接訪問該類的私有變量。即:容許外面的類或函數去訪問類的私有變量和保護變量,從而使兩個類共享同一函數。
實際上具體大概有下面兩種狀況須要使用友元函數:(1)運算符重載的某些場合須要使用友元。(2)兩個類要共享數據的時候。ios

使用友元函數的優缺點
優勢:可以提升效率,表達簡單、清晰。
缺點:友元函數破環了封裝機制,儘可能不使用成員函數,除非不得已的狀況下才使用友元函數。函數

2.友元函數的使用this

友元函數的參數:
由於友元函數沒有this指針,則參數要有三種狀況:
要訪問非static成員時,須要對象作參數
 要訪問static成員或全局變量時,則不須要對象作參數;
若是作參數的對象是全局對象,則不須要對象作參數;spa

友元函數的位置
由於友元函數是類外的函數,因此它的聲明能夠放在類的私有段或公有段且沒有區別。指針

友元函數的調用
能夠直接調用友元函數,不須要經過對象或指針對象

友元函數的分類:
根據這個函數的來源不一樣,能夠分爲三種方法:blog


普通函數友元函數繼承

目的:使普通函數可以訪問類的友元io

語法:
聲明: friend + 普通函數聲明
實現位置:能夠在類外或類中
實現代碼:與普通函數相同
調用:相似普通函數,直接調用class

代碼:

class Interger
{
	friend void Print(const INTEGER& obj);//聲明友元函數
};
void Print(const INTEGER& obj)
{
	//函數體
}
void main()
{
	Interger obj;
	Print(obj);//直接調用
}

  

類Y的全部成員函數都爲類X友元函數—友元類
目的:使用單個聲明使Y類的全部函數成爲類X的友元,它提供一種類之間合做的一種方式,使類Y的對象能夠具備類X和類Y的功能。
語法:
聲明位置:公有私有都可,常寫爲私有(把類當作一個變量)
聲明: friend + 類名(不是對象哦)
代碼:

class girl;
class boy
{
public:
	void disp(girl &);
};
void boy::disp(girl &x) //函數disp()爲類boy的成員函數,也是類girl的友元函數
{
	cout<<"girl's name is:"<<x.name<<",age:"<<x.age<<endl;//藉助友元,在boy的成員函數disp中,藉助girl的對象,直接訪問girl的私有變量
}
class girl
{
private:
  char *name;
  int age;
  friend boy; //聲明類boy是類girl的友元
};

  

類Y的一個成員函數爲類X的友元函數
目的:使類Y的一個成員函數成爲類X的友元,具體而言:在類Y的這個成員函數中,藉助參數X,能夠直接以X的私有變量
語法:
聲明位置:聲明在公有中 (自己爲函數)
聲明:friend + 成員函數的聲明
調用:先定義Y的對象y---使用y調用本身的成員函數---本身的成員函數中使用了友元機制
代碼:
實現代碼和上一代碼中的實現及其類似只是設置友元的時候變爲friend void boy::disp(girl &);

小結:其實一些操做符的重載實現也是要在類外實現的,那麼一般這樣的話,聲明爲類的友元是必須滴。

友元函數和類的成員函數的區別
成員函數有this指針,而友元函數沒有this指針。
友元函數是不能被繼承的,就像父親的朋友未必是兒子的朋友。

友元函數
代碼:

///
 /// @file    friendfunc.cc
 /// @author  Burgess Fan(1406832037@qq.com)
 /// @date    2016-06-20 20:38:18
 ///

#include <iostream>
using namespace std;
class SalesData{
    friend void PrintInfo(SalesData &sdata);
public:
    SalesData(const char*s,unsigned int n,double p)
    :BookNum(s)
    ,SaleNum(n)
    ,BookPrice(p)
    {
        cout<<"SalesData()"<<endl;
    }
    ~SalesData()
    {
        cout<<"~SalesData"<<endl;
    }
private:
    const char* BookNum;
    unsigned int SaleNum;
    double BookPrice;
};
void PrintInfo(SalesData &sdata){
    cout<<"BookNum is:"<<sdata.BookNum<<endl;
    cout<<"SaleNum is:"<<sdata.SaleNum<<endl;
    cout<<"BookPrice is:"<<sdata.BookPrice<<endl;
}
int main(void){
    SalesData s("2016006",10,20.5);
    PrintInfo(s);


    return 0;
}
相關文章
相關標籤/搜索