剖析C++編程中friend關鍵字所修飾的友元函數和友元類
在某些情況下,為不是類成員的函數或單獨類中的所有函數授予成員級別的訪問權會更方便。僅類實現器可以聲明其友元。函數或類不能將其自身聲明為任何類的友元。在類聲明中,使用 friend 關鍵字和非成員函數名稱或其他類,以允許其訪問你的類的專用和受保護成員。
語法
friend class-name; friend function-declarator;
友元聲明
如果聲明以前未聲明的友元函數,則該函數將被導出到封閉非類范圍。
友元聲明中聲明的函數被視為已使用 extern 關鍵字聲明。(有關 extern 的詳細信息,請參閱靜態(tài)存儲類說明符。)
盡管具有全局范圍的函數可以在其原型之前聲明為友元函數,但是成員函數在它們的完整類聲明出現前不能聲明為友元函數。以下代碼演示此失敗的原因:
class ForwardDeclared; // Class name is known. class HasFriends { friend int ForwardDeclared::IsAFriend(); // C2039 error expected };
前面的示例將類名 ForwardDeclared 輸入到范圍中,但是完整的聲明(具體而言,聲明函數 IsAFriend 的部分)是未知的。因此,friend 類中的 HasFriends 聲明會生成一個錯誤。
若要聲明兩個互為友元的類,則必須將整個第二個類指定為第一個類的友元。此限制的原因是該編譯器僅在聲明第二個類的位置有足夠的信息來聲明各個友元函數。
注意
盡管整個第二個類必須是第一個類的友元,但是可以選擇將第一個類中的哪些函數作為第二個類的友元。
友元函數
friend 函數是一個不為類成員的函數,但它可以訪問類的私有和受保護的成員。友元函數不被視為類成員;它們是獲得了特殊訪問權限的普通外部函數。友元不在類的范圍內,除非它們是另一個類的成員,否則不會使用成員選擇運算符(. 和 –>)調用它們。 friend 函數由授予訪問權限的類聲明??蓪?friend 聲明放置在類聲明中的任何位置。它不受訪問控制關鍵字的影響。
以下示例顯示 Point 類和友元函數 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 }
類成員函數可以聲明為其他類中的友元。請看下面的示例:
// 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& ) 授予對類 B 的友元訪問權限。因此,訪問私有成員 _b 在類 Func1 的 A 中是正確的,但在 Func2 中是不正確的。
friend 類是其所有成員函數都是類的友元函數的類,即,其成員函數具有對類的私有成員和受保護成員訪問權限。假定類 friend 中的 B 聲明是:
friend class A;
在這種情況下,將為類 A 中所有成員函數授予對類 B 的友元訪問權限。以下代碼是友元類的示例:
// 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 的私有成員。
托管類型不能具有任何友元函數、友元類或友元接口。
友元關系不能繼承,這意味著從 YourOtherClass 派生的類不能訪問 YourClass 的私有成員。友元關系不可傳遞,因此 YourOtherClass 的友元類無法訪問 YourClass 的私有成員。
下圖顯示了 4 個類聲明:Base、Derived、aFriend 和 anotherFriend。只有類 aFriend 具有對 Base 的私有成員(以及對 Base 可能已繼承的所有成員)的直接訪問權限。
內聯友元定義
可以在類聲明中定義友元函數。這些函數是內聯函數,類似于成員內聯函數,其行為就像它們在所有類成員顯示后但在類范圍關閉前(類聲明的結尾)被定義時的行為一樣。
類聲明中定義的友元函數不被認為在封閉類的范圍內;它們在文件范圍內。
上一篇:C++編程指向成員的指針以及this指針的基本使用指南
欄 目:C語言
本文標題:剖析C++編程中friend關鍵字所修飾的友元函數和友元類
本文地址:http://mengdiqiu.com.cn/a1/Cyuyan/2532.html
您可能感興趣的文章
- 04-02c語言沒有round函數 round c語言
- 01-10深入理解C++中常見的關鍵字含義
- 01-10使用C++實現全排列算法的方法詳解
- 01-10c++中inline的用法分析
- 01-10用C++實現DBSCAN聚類算法
- 01-10全排列算法的非遞歸實現與遞歸實現的方法(C++)
- 01-10C++大數模板(推薦)
- 01-10淺談C/C++中的static與extern關鍵字的使用詳解
- 01-10深入C/C++浮點數在內存中的存儲方式詳解
- 01-10深入理解C/C++混合編程


閱讀排行
本欄相關
- 04-02c語言函數調用后清空內存 c語言調用
- 04-02func函數+在C語言 func函數在c語言中
- 04-02c語言的正則匹配函數 c語言正則表達
- 04-02c語言用函數寫分段 用c語言表示分段
- 04-02c語言中對數函數的表達式 c語言中對
- 04-02c語言編寫函數冒泡排序 c語言冒泡排
- 04-02c語言沒有round函數 round c語言
- 04-02c語言分段函數怎么求 用c語言求分段
- 04-02C語言中怎么打出三角函數 c語言中怎
- 04-02c語言調用函數求fibo C語言調用函數求
隨機閱讀
- 01-11ajax實現頁面的局部加載
- 04-02jquery與jsp,用jquery
- 08-05dedecms(織夢)副欄目數量限制代碼修改
- 01-10delphi制作wav文件的方法
- 01-10使用C語言求解撲克牌的順子及n個骰子
- 08-05織夢dedecms什么時候用欄目交叉功能?
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 01-10SublimeText編譯C開發(fā)環(huán)境設置
- 08-05DEDE織夢data目錄下的sessions文件夾有什
- 01-10C#中split用法實例總結