1. 程式人生 > >【C++】友元與靜態成員

【C++】友元與靜態成員

友元

C++中,類外的成員不能訪問類內的私有和保護型別成員。而友元函式可以不受訪問限制訪問類的任何成員。友元函式雖然可以在類內進行宣告,但是友元函式不是成員函式,因此沒有this指標。
舉例說明:

class Clock
{
public:
    Clock(int, int, int);
    friend void Show(Clock &);
private:
    int hour;
    int minute;
    int second;
};
Clock::Clock(int h, int m, int s)
{
    hour = h;
    minute
= m; second = s; } void Show(Clock& c) { cout << c.hour << ":" << c.minute << ":" << c.second << endl; } int main() { Clock c(8, 10, 12); Show(c); return 0; }

一般來說,友元函式帶有一個與其有好友關係的類型別的入口引數。因為友元函式不是與其有好友關係的類的成員函式,它沒有this指標,所以它不能直接引用類成員的名字。它必須通過作為入口引數傳遞進來的物件名或物件指標來引用該物件的成員。
如上例子,Show函式的引數是一個Clock型別的引用,可以利用引用來訪問友元函式的好友類的私有成員。

class Clock
{
public:
    Clock(int, int, int);
    void Show();
private:
    int hour;
    int minute;
    int second;
};
Clock::Clock(int h, int m, int s)
{
    hour = h;
    minute = m;
    second = s;
}
void Clock::Show()
{
    cout << hour << ":" << minute << ":" << second
<< endl; } int main() { Clock c(8, 10, 12); c.Show(); return 0; }

而上述程式碼是將Show()宣告為成員函式,利用this指標來訪問該類的私有資料。
那麼,友元函式究竟有什麼用呢?
首先,友元機制是對類的封裝機制的補充,利用這種機制,一個類可以賦予某些函式訪問它的私有成員的特權。宣告一個類的友元函式,就可以用這個函式直接訪問該類的私有資料,從而提高程式執行的效率。
其次,友元提供了不同類的成員函式之間、類的成員函式和普通函式之間進行資料共享的機制。尤其當一個函式需要訪問多個類的私有成員時,友元函式非常有用。普通的成員函式只能訪問其所屬類的私有成員,但是多個類的友元函式能夠訪問相關所有類的私有成員。

友元函式的宣告可以出現在類的任何地方,(包括在public和private部分)也就是說友元的宣告不受成員訪問控制符的限制。
友元的關係是單向的,而不是雙向的。如果聲明瞭B是A的友元類,不等於A類也是B類的友元類,A類中的成員函式不一定能夠訪問B類的成員。
友元關係不能傳遞。

靜態成員

在C++中,要實現類的多個物件之間的資料共享,可使用靜態成員。靜態成員包括兩種,一種是靜態資料成員,另一種是靜態成員函式。
類的普通資料成員在類的每個物件中都擁有一個拷貝,就是說每個物件的同名數據成員可以分別儲存不同的數值,這也保證物件擁有自身區別於其他物件的特徵需要。但是靜態資料成員每個類只有一個拷貝,由該類所有物件共同維護和使用,從而實現了同一個類的不同物件之間的資料共享。
靜態資料成員在記憶體中只佔用一份儲存空間,它是屬於類的,但是它被該類的所有物件所共享,每個物件都可以訪問這個靜態資料成員。靜態資料成員的值對所有物件都是一樣的。如果改變它的值,則在各個物件中這個資料成員的值都同時變了。可以節約空間,提高效率。
如果只聲明瞭類而未定義物件,則類的一般資料成員是不佔儲存空間的,只有在定義物件時,才為物件的資料成員分配空間。但是靜態資料成員不屬於某一個物件,在為物件開闢空間的同時並不會為靜態資料成員分配空間。靜態資料成員是在所有物件之外單獨開闢空間。它是在程式編譯時被分配空間的,到程式結束時才釋放空間。