C ++友元的淺析(一)

一、友元函數定義:友元函數是指某些雖然不是類成員卻能夠訪問類的所有成員的函數。。類授予它的友元特別的訪問權。通常同一個開發者會出於技術和非技術的原因,控制類的友元和成員函數(否則當你想更新你的類時,還要徵得其它部分的擁有者的同意);類具有封裝和信息隱藏的特性。只有類的成員函數才能訪問類的私有成員,程序中的其他函數是無法訪問私有成員的。非成員函數可以訪問類中的公有成員,但是如果將數據成員都定義爲公有的,這又破壞了隱藏的特性。另外,應該看到在某些情況下,特別是在對某些成員函數多次調用時,由於參數傳遞,類型檢查和安全性檢查等都需要時間開銷,而影響程序的運行效率。

二、友元函數案例

1.全局友元函數

    如果這個函數不是定義在class中,並且它可以用來操作其他class的私有屬性,稱之爲全局友元函數。案例如下:

#include <iostream>

using namespace std;

class A{
private:
    int a;
public:
    //申明友元函數
    friend void show(A &a);
    A(){
        cout << "類A被構造" << endl;
        a = 20;
    }
    ~A(){
        cout << "類A被析構" << endl;
    }
};

//全局友元函數
void show(A &a){
    //訪問classA的私有成員
    cout << "a="<<a.a <<endl;
}

class B{
private:
    int b;
public:
    B(){
        A a;
        show(a);
        cout << "類B的構造" << endl;
        b = 12;
    }
    ~B(){
        cout << "類B被析構" << endl;
    }
};

int main(){
    B b;
    return 0;
}
上述案例中void show(A &a)  爲全局友元函數,他可以訪問class A 的私有成員a,可以這樣理解,函數void show(...)是class A的朋友,故它可以訪問classA的資源。定義友元函數很簡單,只需要在class A中申明show函數,並在申明前添加frien關鍵字

2.友元類

友元除了前面講過的函數以外,友元還可以是類,即一個類可以作另一個類的友元。當一個類作爲另一個類的友元時,這就意味着這個類的所有成員函數都是另一個類的友元函數。案例如下:

#include <iostream>

using namespace std;

class A{
private:
    int a;
public:
    friend class B;
    A(){
        cout << "類A被構造" << endl;
        a = 20;
    }
    ~A(){
        cout << "類A被析構" << endl;
    }
};



class B{
private:
    int b;
public:
    B(){
        A a;
        show(a);
        cout << "類B的構造" << endl;
        b = 12;
    }
    ~B(){
        cout << "類B被析構" << endl;
    }
    //友元類函數
    void show(A &a){
        //訪問classA的私有成員
        cout << "a="<<a.a <<endl;
    }
};

int main(){
    B b;
    return 0;
}
在class 中定義了friend class B;即class B 爲classA的友元類,classB 中的所有成員函數都是classA的友元函數,它們可以訪問classA 中的私有成員.注意這時,友元是單向的,這時class A 中的函數不能訪問class B中的內容。

3.互爲友元類

   如何實現classA與B互爲友元,即A可以訪問B的私有,B也可以訪問A的私有呢?案例如下:

#include <iostream>

using namespace std;
//必須提前聲明class B不然編譯會報錯
class B;
class A{
private:
    int a;
public:
    friend class B;

    A(){
        cout << "類A被構造" << endl;
        a = 20;
    }
    ~A(){
        cout << "類A被析構" << endl;
    }
    void show(B & b);
};

class B{
private:
    int b;
public:
    friend class A;
    B(){
        cout << "類B的構造" << endl;
        b = 12;
    }
    ~B(){
        cout << "類B被析構" << endl;
    }
    void show(A &a){
        cout << "a="<<a.a ;
        cout << " b=" <<b<<endl;
    }
};
//函數不能放在class A 中,不然會編譯報錯
void A::show(B &b){
    cout << "a="<<a ;
    cout << " b="<<b.b<< endl;
}

int main(){
    A a;
    B b;
    a.show(b);
    b.show(a);

    return 0;
}
運行結果:

類A被構造
類B的構造
a=20 b=12
a=20 b=12
類B被析構
類A被析構
互爲友元類的做法就是,在classA中聲明friend class B;在classB 中聲明friend class A;
注意:類A中使用到了類B的地方必須在類B的聲明後定義,在類A中只能聲明。例如左邊類A中的show函數,不能在類A中直接定義,只能放在類B的聲明之後定義。

文章出處:http://www.th7.cn/Program/cp/201411/320603.shtml


   

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章