【C++ 筆記】Friend Classes & Functions - part 19 === 目錄(Table of Contents): [TOC] --- 很感謝你點進來這篇文章。 你好,我並不是什麼 C++、程式語言的專家,所以本文若有些錯誤麻煩請各位鞭大力一點,我極需各位的指正及指導!!本系列文章的性質主要以詼諧的口吻,一派輕鬆的態度自學程式語言,如果你喜歡,麻煩留言說聲文章讚讚吧! Friend Class --- Friend Class 可以直接存取其他 class 的 private、protected 成員,只要當這個 class 被宣告為 `friend`。 因為 private、protected 成員不能直接存取,所以可以用 friend 的方式指定某 class 為好友 class,這在某些時候會變得很好用,如常見的 Data Structure:Linked-list。 宣告一個 friend class 格式如下: ```cpp friend class class_name; // declared in the base class ``` 以下是個範例: ```cpp= #include <iostream> using namespace std; class Base { private: int privateValue = 10; protected: int protectedValue = 20; public: // 宣告 FriendClass 為朋友類別 friend class FriendClass; void showBase() { cout << "From Base: private=" << privateValue << ", protected=" << protectedValue << endl; } }; class FriendClass { public: void accessBase(Base& b) { // 可直接存取 Base 的 private 和 protected 成員 cout << "From FriendClass: private=" << b.privateValue << ", protected=" << b.protectedValue << endl; // 也可修改這些成員 b.privateValue = 100; b.protectedValue = 200; } }; int main() { Base baseObj; FriendClass friendObj; cout << "原始值:" << endl; baseObj.showBase(); friendObj.accessBase(baseObj); cout << "修改後的值:" << endl; baseObj.showBase(); return 0; } ``` 輸出結果: ``` 原始值: From Base: private=10, protected=20 From FriendClass: private=10, protected=20 修改後的值: From Base: private=100, protected=200 ``` 由上例可知:通常 friend 都宣告在要指定 friend 的 class 裡面,之後在外面額外宣告一個 friend class,從而存取 Base Class 裡面的成員。 總之,以上範例具有以下四種意義: 1. `Base` class 透過 `friend class FriendClass` 宣告將 `FriendClass` 設為朋友類別 2. `FriendClass` 可以直接存取 `Base` 的 `private` 和 `protected` 成員 3. 除存取外,也能直接修改這些成員。 4. 原本 private 和 protected 成員無法直接從外部存取,僅能透過 friend 關係才可直接存取 Friend Function --- 功能基本上跟 Friend Class 相同,但要注意 Friend Function 並不是類別中的成員函數,還是能跟 Friend Class 一樣存取 private、protected。 Friend Function 可為: 1. 全域函數(Global Function):字面上意思,就是"全域"函數。 2. 別的 Class 中的成員函數(Member Function) 以下是其格式: ```cpp= friend return_type function_name (arguments); // for a global function or friend return_type class_name::function_name (arguments); // for a member function of another class ``` 以下是個範例(Global Function): ```cpp= #include <iostream> using namespace std; class Base { private: int privateValue = 10; protected: int protectedValue = 20; public: // 宣告 FriendClass 為朋友類別 friend class FriendClass; // 宣告朋友函數 friend void friendFunction(Base& b); void showBase() { cout << "From Base: private=" << privateValue << ", protected=" << protectedValue << endl; } }; class FriendClass { public: void accessBase(Base& b) { cout << "From FriendClass: private=" << b.privateValue << ", protected=" << b.protectedValue << endl; b.privateValue = 100; b.protectedValue = 200; } }; // 朋友函數的定義(不是任何類別的成員) void friendFunction(Base& b) { cout << "From friendFunction: private=" << b.privateValue << ", protected=" << b.protectedValue << endl; // 同樣可以修改 private 和 protected 成員 b.privateValue = 300; b.protectedValue = 400; } int main() { Base baseObj; FriendClass friendObj; cout << "原始值:" << endl; baseObj.showBase(); friendObj.accessBase(baseObj); cout << "經 FriendClass 修改後:" << endl; baseObj.showBase(); friendFunction(baseObj); cout << "經 friendFunction 修改後:" << endl; baseObj.showBase(); return 0; } ``` 輸出結果: ``` 原始值: From Base: private=10, protected=20 From FriendClass: private=10, protected=20 經 FriendClass 修改後: From Base: private=100, protected=200 From friendFunction: private=100, protected=200 經 friendFunction 修改後: From Base: private=300, protected=400 ``` 在上個範例 Friend Class 的基礎下,新增了 Friend Function,可見功能仍相同。 以下是第二個範例(member function of another class): Source:https://www.geeksforgeeks.org/friend-class-function-cpp/ ```cpp= // C++ program to create a member function of another class // as a friend function #include <iostream> using namespace std; class base; // forward definition needed (需要在 anotherClass 前面定義) // another class in which function is declared class anotherClass { public: void memberFunction(base& obj); // 這裡跟 base class 有關 }; // base class for which friend is declared class base { private: int private_variable; protected: int protected_variable; public: base() { private_variable = 10; protected_variable = 99; } // friend function declaration (朋友函數宣告) friend void anotherClass::memberFunction(base&); }; // friend function definition void anotherClass::memberFunction(base& obj) { cout << "Private Variable: " << obj.private_variable << endl; cout << "Protected Variable: " << obj.protected_variable; } // driver code int main() { base object1; anotherClass object2; object2.memberFunction(object1); return 0; } ``` 輸出結果: ``` Private Variable: 10 Protected Variable: 99 ``` ### Friend Function 注意事項 --- * 關鍵字「friend」僅放在 Friend Function 的函數宣告中,而不放在函數定義或呼叫中。 * Friend Function 的呼叫方式與普通函數類似。不能用物件名稱和點運算子 "." 來呼叫它。但它可接受該物件作為它想要存取其值的參數。 * Friend Function可以在類別的任何部分宣告,即在 public、private、protected 都可。 * 定義另一個類別的 Friend Function 的順序很重要。必須要在函數定義之前定義兩個 class。這就是為什麼用類別外成員函數定義的原因。 參考資料 --- [friend 函式、friend 類別](https://openhome.cc/Gossip/CppGossip/friendFunctionClass.html) [Friend Class and Function in C++ - GeeksforGeeks](https://www.geeksforgeeks.org/friend-class-function-cpp/) [friend (C++) | Microsoft Learn](https://learn.microsoft.com/zh-tw/cpp/cpp/friend-cpp?view=msvc-170) [C++ 友元函数 | 菜鸟教程](https://www.runoob.com/cplusplus/cpp-friend-functions.html)