了解虛擬函數和純虛擬函數
虛擬函數透過啟用運行時多態性在物件導向程式設計中發揮著至關重要的作用。根據維基百科的定義,虛擬函數是允許動態分派的可重寫方法或函數。這意味著要執行的具體函數是在運行時根據物件的類型確定的,而不是在編譯時。
與非虛函數相反,當在衍生類別中重寫虛擬函數時,在最衍生類別中定義的版本在整個類別層次結構中使用。這確保了始終利用該函數的最具體實現。
純虛函數,也稱為純虛方法,進一步發展了這個概念。它們是虛函數,如果衍生類別不是抽象類,則必須在該衍生類別中實作它們。因此,純虛函數有效地要求在衍生類別中存在特定行為。
抽象類別是包含一個或多個純虛函數的類別。此類類別不能直接實例化;相反,必須使用為所有純虛函數提供實現的衍生類別。
為了說明虛函數和純虛函數之間的差異,請考慮以下 C code:
Base.hpp:
struct Base { virtual ~Base() = default; virtual void foo() { std::cout << "Base::Foo" << std::endl; } };
推導d.hpp:
struct Derived : public Base { void foo() override { std::cout << "Derived::Foo" << std::endl; } };
main.cpp:
int main() { Base base; base.foo(); // Calls Base::Foo Derived derived; derived.foo(); // Calls Derived::Foo Base* derived_as_base = &derived; derived_as_base->foo(); // Calls Derived::Foo (due to dynamic dispatch) }
中這段程式碼中,Base類別包含一個虛擬函數 foo,它列印“Base::Foo”。 Derived 類別重寫此函數以列印「Derived::Foo」。當 Base 物件呼叫 foo 時,輸出為「Base::Foo」。然而,當 Derived 物件(作為 Base 指標存取)呼叫 foo 時,由於動態調度,輸出為「Derived::Foo」。
現在,讓我們考慮一個純虛擬函數:
PureBase.hpp:
struct PureBase { virtual ~PureBase() = default; virtual void foo() = 0; // Pure virtual function };
PureDerived.hhpp:Derived. >
struct PureDerived : public PureBase { void foo() override { std::cout << "PureDerived::Foo" << std::endl; } };在此程式碼中, PureBase 類別包含一個未在基底類別中定義的純虛函數 foo。因此,PureBase 類別是抽象的,因為它缺乏完整的實作。
PureMain.cpp:
int main() { // error: cannot declare variable 'pureBase' to be of abstract type 'PureBase' // PureBase pureBase; // pureBase.foo(); PureDerived pureDerived; pureDerived.foo(); // Calls PureDerived::Foo }在此範例中,嘗試實例化 PureBase物件直接導致編譯器錯誤。但是,建立 PureDerived 物件是允許的,因為它提供了 foo 函數的實作。 總而言之,虛擬函數提供動態調度,並且可以在衍生類別中重寫。另一方面,純虛函數需要在衍生類別中實作並強制執行特定的行為。這些概念共同在物件導向程式設計中實現多型功能方面發揮著至關重要的作用。
以上是物件導向程式設計中的虛函數和純虛函數有什麼不同?的詳細內容。更多資訊請關注PHP中文網其他相關文章!