一、概念解析
C++ 中,虛函數表(Virtual Function Table)用於實現多態,是實現C++類為基本的Object-oriented思想的重要工具之一。虛函數表是一個數據結構,存儲著該類對象中所有虛函數的地址信息,使得在代碼執行中可以正確地調用到當前對象所屬的類的實現。
二、實現原理
C++ 虛函數表的實現原理是通過將虛函數的地址存儲在虛函數表中,在函數調用時通過虛函數表中的地址來找到正確的函數並進行調用。
class Base { public: virtual void foo() { cout << "Base::foo()" << endl; } virtual void bar() { cout << "Base::bar()" << endl; } }; class Derived : public Base { public: void foo() override { cout << "Derived::foo()" <foo(); // Derived::foo() ptr->bar(); // Base::bar() return 0; }
在上述代碼中,由於虛函數表中存儲了 Derived::foo() 的地址信息,所以當執行 ptr->foo() 時會執行 Derived::foo(),而在虛函數表中找不到 Derived::bar() 的地址,則會執行Base::bar()。
三、虛函數表的構造與析構
虛函數表的構造和析構涉及對象的創建和銷毀,C++ 約定虛函數表與對象一起構造和銷毀。
當定義一個類時,編譯器會自動生成該類的虛函數表並初始化,將每個虛函數的地址存儲在該類的虛函數表中。
class Base { public: virtual void foo() { cout << "Base::foo()" << endl; } virtual void bar() { cout << "Base::bar()" << endl; } }; class Derived : public Base { public: void foo() override { cout << "Derived::foo()" <foo(); // Derived::foo() delete ptr; return 0; }
在上述代碼中,Derived 對象被創建後其虛函數表會存放在該對象的內存的開頭,當刪除 Derived 對象時也會清除相應的虛函數表。
四、虛函數表與多重繼承
在多重繼承中,一個對象可能會有多個虛函數表。C++ 會對這些虛函數表進行處理使得存儲在每個虛函數表中的函數地址不發生衝突。
class A { public: virtual void foo() { cout << "A::foo()" << endl; } }; class B { public: virtual void bar() { cout << "B::bar()" << endl; } }; class C : public A, public B { public: void foo() override { cout << "C::foo()" << endl; } void bar() override { cout << "C::bar()" << endl; } }; int main() { C* ptr = new C(); A* ptr_a = static_cast(ptr); B* ptr_b = static_cast(ptr); ptr_a->foo(); // C::foo() ptr_b->bar(); // C::bar() delete ptr; return 0; }
上述代碼中 C 類繼承了 A 和 B 兩個類,在創建 C 對象時,該對象會有兩個虛函數表,存儲各自的虛函數的地址。在使用 static_cast 將 C 對象轉換為 A 和 B 指針時,會調用各自虛函數表中存儲的地址來執行相應的函數。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/157611.html