共用方式為


friend (C++)

在某些情況下,類別將不屬於類別成員的函式,或授與個別類別中所有成員的成員層級存取權會很有用。 這些免費函式和類別稱為 friend,並以 關鍵詞標示 friend 。 只有類別實作器可以宣告其朋友是誰。 函式或類別無法將自己宣告為任何類別的朋友。 在類別定義中,使用 friend 非member函式或其他類別的 關鍵詞和名稱,將類別的私人和受保護成員的存取權授與它。 在樣本定義中,類型參數可以宣告為 friend

語法

friend-declaration
friend function-declaration
friend function-definition
friend elaborated-type-specifier ;;
friend simple-type-specifier ;
friend typename-specifier ;

friend 聲明

如果您宣告 friend 先前未宣告的函式,該函式會匯出至封入的非類別範圍。

宣告中 friend 宣告的函式會被視為使用 extern 關鍵詞宣告的函式。 如需詳細資訊,請參閱extern

雖然具有全域範圍的函式可以在原型之前宣告為 friend 函式,但是成員函式無法在完整類別宣告的外觀之前宣告為 friend 函式。 下列程式代碼顯示這類宣告如何失敗:

class ForwardDeclared;   // Class name is known.
class HasFriends
{
    friend int ForwardDeclared::IsAFriend();   // C2039 error expected
};

上述範例會將類別名稱 ForwardDeclared 輸入範圍,但不知道完整宣告(特別是宣告 IsAFriend函式的部分)。 類別friendHasFriends中的宣告會產生錯誤。

在 C++11 中,類別有兩種形式的 friend 宣告:

friend class F;
friend F;

第一個窗體會在最內層命名空間中找到該名稱的現有類別時,引進新的類別 F。 C++11:第二個窗體不會引進新的類別;當類別已經宣告時可以使用,而且在宣告樣板類型參數或 typedef 做為 friend時必須使用它。

當參考的類型尚未宣告時使用 friend class F

namespace NS
{
    class M
    {
        friend class F;  // Introduces F but doesn't define it
    };
}

如果您搭配未宣告的類別類型使用 friend ,就會發生錯誤:

namespace NS
{
    class M
    {
        friend F; // error C2433: 'NS::F': 'friend' not permitted on data declarations
    };
}

在下列範例中, friend F 是指 F 在 NS 範圍之外宣告的 類別。

class F {};
namespace NS
{
    class M
    {
        friend F;  // OK
    };
}

使用 friend F 將範本參數宣告為friend:

template <typename T>
class my_class
{
    friend T;
    //...
};

使用 friend F 將 typedef 宣告為 friend:

class Foo {};
typedef Foo F;

class G
{
    friend F; // OK
    friend class F // Error C2371 -- redefinition
};

若要宣告兩個類別是彼此的朋友,必須將整個第二個類別指定為第一類的朋友。 此限制的原因是編譯程式有足夠的資訊,只能在宣告第二個類別的點宣告個別friend函式。

備註

雖然整個第二類必須是第一類的朋友,但您可以選取第一類中的哪些函式將是第二類的朋友。

friend 函式

friend 式不是類別的成員,但可以存取類別的私人和受保護的成員。 Friend 函式不會被視為類別成員;它們是一般外部函式,提供特殊存取許可權。 Friend 不在類別的範圍中,除非是另一個類別的成員,否則不會使用成員選取運算符 ( ->) 來呼叫。 函 friend 式是由授與存取權的類別所宣告。 宣告 friend 可以放在類別宣告中的任何位置。 它不會受到訪問控制關鍵詞的影響。

下列範例顯示 Point 類別和friend 函式 ChangePrivate。 函 friend 式可以存取其接收做為參數之 Point 物件的私用數據成員。

// friend_functions.cpp
// compile with: /EHsc
#include <iostream>

using namespace std;
class Point
{
    friend void ChangePrivate( Point & );
public:
    Point( void ) : m_i(0) {}
    void PrintPrivate( void ){cout << m_i << endl; }

private:
    int m_i;
};

void ChangePrivate ( Point &i ) { i.m_i++; }

int main()
{
   Point sPoint;
   sPoint.PrintPrivate();
   ChangePrivate(sPoint);
   sPoint.PrintPrivate();
// Output: 0
           1
}

以朋友身分的類別成員

類別成員函式可以宣告為其他類別中的friend。 請考慮下列範例:

// classes_as_friends1.cpp
// compile with: /c
class B;

class A {
public:
   int Func1( B& b );

private:
   int Func2( B& b );
};

class B {
private:
   int _b;

   // A::Func1 is a friend function to class B
   // so A::Func1 has access to all members of B
   friend int A::Func1( B& );
};

int A::Func1( B& b ) { return b._b; }   // OK
int A::Func2( B& b ) { return b._b; }   // C2248

在上述範例中 A::Func1( B& ) ,只會將 函式的存取權授與 friend 類別 B。 因此,在類別AFunc1存取私用成員_b是正確的,但在 中Func2則不是 。

類別 friend 是類別,其成員函式都是 friend 類別的函式,也就是說,其成員函式可以存取其他類別的私人和受保護的成員。 friend假設 類別B中的宣告是:

friend class A;

在此情況下,類別中的所有 A 成員函式都會被授與 friend 類別的 B存取權。 下列程式代碼是 類別 friend 的範例:

// classes_as_friends2.cpp
// compile with: /EHsc
#include <iostream>

using namespace std;
class YourClass {
friend class YourOtherClass;  // Declare a friend class
public:
   YourClass() : topSecret(0){}
   void printMember() { cout << topSecret << endl; }
private:
   int topSecret;
};

class YourOtherClass {
public:
   void change( YourClass& yc, int x ){yc.topSecret = x;}
};

int main() {
   YourClass yc1;
   YourOtherClass yoc1;
   yc1.printMember();
   yoc1.change( yc1, 5 );
   yc1.printMember();
}

除非明確指定為,否則友誼不是相互的。 在上述範例中,的成員 YourClass 函式無法存取 的私用 YourOtherClass成員。

Managed 類型 (在 C++/CLI 中) 不能有任何 friend 函式、 friend 類別或 friend 介面。

友誼不會繼承,這表示衍生自 YourOtherClass 的類別無法存取 YourClass的私用成員。 友誼不是可轉移的,所以那些是朋友 YourOtherClass 的班級無法存取 YourClass的私人成員。

下圖顯示四個類別宣告: BaseDerivedaFriendanotherFriend。 只有類別 aFriend 可以直接存取 的私用成員 Base (以及可能繼承的任何成員 Base )。

顯示friend關聯性衍生含意的圖表。

此圖顯示另一個朋友的類別與朋友類類別的類別基底沒有朋友關係。 類別 AFriend 是由類別基底所交友,但即使類別 Derived 繼承自 Base,它也沒有與衍生類別的 friend 關聯性。 這示範繼承並不表示衍生類別與基類具有相同的朋友。

內嵌 friend 定義

Friend 函式可以在類別宣告內定義(指定函式主體)。 這些函式是內嵌函式。 如同成員內嵌函式,它們的行為就像是在看到所有類別成員之後立即定義,但在類別範圍關閉之前(在類別宣告的結尾)。 類別宣告內定義的Friend函式位於封入類別的範圍內。

另請參閱

關鍵字