目錄
- 1. 概念
- 2. 示例
- 3. 總結
在C++中,加上 virtual
關鍵字可以實現多型,這是因為它允許函式在基類和派生類中有不同的實現,並確保在執行時正確呼叫派生類的方法。具體來說,這種機制稱為“動態繫結”或“執行時多型”。
1. 概念
-
虛擬函式(Virtual Function):
當你在基類中宣告一個函式為virtual
時,C++ 會為該函式在類的物件中建立一個虛擬函式表(vtable)。虛擬函式表是一個指標陣列,其中每個元素指向類中虛擬函式的實現。每個類物件都有一個指向其虛擬函式表的指標(vptr)。 -
虛擬函式表(vtable):
虛擬函式表包含了指向該類中虛擬函式實現的指標。基類和每個派生類都有自己的虛擬函式表。基類中的虛擬函式表包含基類中虛擬函式的地址,派生類中的虛擬函式表則可能包含不同的地址,指向派生類中重寫的虛擬函式實現。 -
動態繫結(Dynamic Binding):
當透過基類指標或引用呼叫虛擬函式時,C++ 執行時會透過虛擬函式表來決定實際呼叫哪個類的實現。這意味著,即使你使用的是基類的指標或引用,實際呼叫的仍然是派生類的實現,這取決於指標或引用所指向的物件的實際型別。
2. 示例
假設你有以下類結構:
class Animal {
public:
virtual void speak() {
cout << "動物在說話" << endl;
}
};
class Cat : public Animal {
public:
void speak() override {
cout << "小貓在說話" << endl;
}
};
如果你建立一個 Cat
物件並透過 Animal
指標呼叫 speak
方法:
Animal* animal = new Cat();
animal->speak();
雖然 animal
是 Animal
型別的指標,但因為 speak
是虛擬函式,程式會使用 animal
物件的 vptr,查詢 Cat
的虛擬函式表,並呼叫 Cat
類中實現的 speak
方法。這會輸出 小貓在說話
。
3. 總結
加上 virtual
關鍵字使得函式呼叫可以在執行時根據物件的實際型別動態決定呼叫哪個函式,從而實現了多型。虛擬函式表和虛擬函式指標的機制允許不同型別的物件在執行時執行正確的函式實現,這是物件導向程式設計中多型性的核心特性。