靜態多態(編譯期)
函數重載:
- 允許在同一個作用域中聲明多個功能類似的同名函數
- 函數的參數列表不同(參數個數,參數類型,參數順序)
- 注意:不能通過函數返回值區分(name mangling不包括返回值)
原理:
- 預編譯:頭文件的函數聲明拷貝到源文件,避免編譯過程找不到函數定義
- 編譯:語法分析,同時進行符號匯總(函數名)
- 匯編:生成函數名到函數地址的映射,方便之后通過函數名找到函數定義的位置
- 鏈接:將多個文件的符號表匯總合并
*objdump -t o
- _ZN + 類長度+ 類名+ 函數名長度 + 函數名 + E + 類型首字母
模版:
- 編譯期間進行實例化
- 性能要高,避免了運行時的開銷
動態多態
虛函數重寫,運行時確定
- 在基類的函數前面加上
virtual
關鍵字,派生類重寫函數 - 運行時根據對象的類型調用相應的函數
- 如果對象的類型是基類,則調用基類的函數
- 如果對象的類型是派生類,調用派生類的函數
原理:
- 早綁定:編譯時已經確定函數調用的地址
- 晚綁定:需要用到虛函數表,運行時才能確定
早綁定(Early Binding)
早綁定,也稱為靜態綁定(Static Binding),是在編譯時確定函數調用的具體實現。這意味著在編譯階段,編譯器已經知道函數調用對應的具體函數。早綁定通常與非虛函數、函數重載和模板有關。
早綁定的優點:
- 性能高,因為函數調用在編譯時已確定,不需要運行時查找。
- 類型安全,因為編譯器在編譯時進行類型檢查,可以捕捉到類型不匹配的錯誤。
示例:
#include <iostream>
using namespace std;class Base {
public:void display() {cout << "Base display" << endl;}
};class Derived : public Base {
public:void display() {cout << "Derived display" << endl;}
};int main() {Base b;Derived d;Base *ptr = &d;ptr->display(); // 調用 Base::display()return 0;
}
在上述示例中,ptr->display()
是早綁定,因為編譯器在編譯時已經知道 ptr
是 Base
類型的指針,并且調用 Base
類的 display
函數。
晚綁定(Late Binding)
晚綁定,也稱為動態綁定(Dynamic Binding),是在運行時確定函數調用的具體實現。這通常通過虛函數(virtual functions)和多態性實現。晚綁定依賴于虛函數表(vtable),通過指針在運行時查找函數的具體實現。
晚綁定的優點:
- 靈活性高,允許程序在運行時決定調用哪個函數。
- 支持多態性,使得可以通過基類指針調用派生類的實現。
示例:
#include <iostream>
using namespace std;class Base {
public:virtual void display() {cout << "Base display" << endl;}
};class Derived : public Base {
public:void display() override {cout << "Derived display" << endl;}
};int main() {Base *ptr = new Derived();ptr->display(); // 調用 Derived::display()delete ptr;return 0;
}
在上述示例中,ptr->display()
是晚綁定,因為 display
是虛函數,具體調用的函數是在運行時根據對象的實際類型(即 Derived
)決定的。
最后給大家推薦一個LinuxC/C++高級架構系統教程的學習資源與課程,可以幫助你有方向、更細致地學習C/C++后端開發,具體內容請見 https://xxetb.xetslk.com/s/1o04uB