虛擬函式和虛擬函式表
阿新 • • 發佈:2019-02-04
虛擬函式的作用:用於實現C++的多型。
虛擬函式表:具有虛擬函式的類在編譯階段會建立一個虛擬函式表vtable。
虛擬函式指標:每個類物件有一個虛擬函式指標vptr,vptr指向vtable。
虛擬函式表是虛擬函式指標的陣列
多重繼承的虛擬函式表:
在派生類Derived虛擬函式表中,派生類的虛擬函式f()會覆蓋所有基類的f()
同時,派生類的其它虛擬函式g1()會放在第一個基類的虛擬函式表後面
class Base1 { public: Base1() { cout << "Base1::Base1()" << endl; } virtual void f() { cout << "Base1::f()" << endl; } virtual void g() { cout << "Base1::g()" << endl; } virtual void h() { cout << "Base1::h()" << endl; } }; class Base2 { public: Base2() { cout << "Base2::Base2()" << endl; } virtual void f() { cout << "Base2::f()" << endl; } virtual void g() { cout << "Base2::g()" << endl; } virtual void h() { cout << "Base2::h()" << endl; } }; class Derived : public Base1, public Base2 { public: Derived() { cout << "Derived::Derived()" << endl; } void f() { cout << "Derived::f()" << endl; } virtual void g1() { cout << "Derived::g1()" << endl; } }; void printDerived(Derived &d) { cout << endl << "print all vtable:" << endl; int i = 0, j = 0; typedef void(*Fcn)(); while (i < 2) { Fcn vfcn = (Fcn)*((int*)(*((int*)&d + i)) + j); cout << "Base" << i + 1 << "::vtable:" << endl; while (vfcn) { vfcn(); ++j; vfcn = (Fcn)*((int*)*((int*)&d + i) + j); } ++i; j = 0; } } void test() { Derived d; printDerived(d); }
win32下:
Base1虛擬函式表的地址:(int*)&d + 0
Base2虛擬函式表的地址:(int*)&d + 1
Base1虛擬函式表第1個虛擬函式指標的地址:(int*)*((int)&d + 0) + 0
Base1虛擬函式表第2個虛擬函式指標的地址:(int*)*((int)&d + 0) + 1
Base1虛擬函式表第3個虛擬函式指標的地址:(int*)*((int)&d + 0) + 2
Base2虛擬函式表第1個虛擬函式指標的地址:(int*)*((int)&d + 1) + 0
Base2虛擬函式表第2個虛擬函式指標的地址:(int*)*((int)&d + 1) + 1
Base2虛擬函式表第3個虛擬函式指標的地址:(int*)*((int)&d + 1) + 2
多重繼承虛擬函式表示意圖: