---
# System prepended metadata

title: 技術｜C++｜C++ Virtual 函數

---

# 技術｜C++ ｜C++ Virtual 函數

- 虛擬函數 virtual function
    - 使用 `reference/pointer` 呼叫 base 類別的 `virtual function` 時，會觸發 dynamic binding，這種時候 runtime 才會知道要呼叫哪一個函數
    - 底層是使用 virtual table 和 virtual pointer
        - virtual table 在編譯期就準備好了
        - `每一個定義的類別會有一張共用的 virtual table`
        - `每一個實體化的物件，會有 virtual pointer 指向共用的 virtual table`
        - 當遇到 dynamic binding 時，根據底層物件的 virtual table，決定要呼叫哪一個函數
    - ![](https://i.imgur.com/Lz7EcCR.png)
    - 細節
        - virtual function 在被繼承的時候，編譯器會幫忙補上 virtual 關鍵字
        - 指定 `override` 關鍵字，覆寫父類別的函數實作
        - 指定 `final` 關鍵字在，讓之後的衍生類別不能覆寫
        - base/dericed 的虛擬函數，interface 必須完全相同
            - 參數完全相同
            - 回傳值完全相同
## Dynamic Binding 和 default augument
- 函數呼叫 dynamic binding 是根據 virtual table
- 預設參數是根據靜態類型（即指針類型）
    ```c++=
    #include <iostream>
    using namespace std;

    class A {
    public:
        virtual void f(int n = 7) {
            cout << "A" << " " << n << endl;
        };
    };
    class B : public A {
    public:
        void f(int n = 9) {
            cout << "B" << " " << n << endl;
        };
    };

    int main() {
        A *pa = new A, *pb = new B;
        B *pc = new B;
        pa->f(); // A 7
        pb->f(); // B 7
        pc->f(); // B 9
    }
    ```