---
# System prepended metadata

title: 【C++ 筆記】Friend Classes & Functions - part 19
tags: [物件導向程式設計, 程式設計, C++, 程式語言, OOP]

---

【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)