单继承与多继承中的虚函数表和虚函数指针
首先,我们了解一下何为单继承,何为多继承??
单继承:一个子类只有一个直接父类。
多继承:一个子类有两个或多个直接父类。
单继承中的虚函数表分析:
示例程序:
- #include <iostream>
- using namespace std;
- typedef void(*FUNC)();
- class Base
- {
- public:
- virtual void func1()
- {
- cout << "Base::func1()" << endl;
- }
- virtual void func2()
- {
- cout << "Base::func2()" << endl;
- }
- private:
- int _b;
- };
- class Derive :public Base
- {
- public:
- virtual void func1()
- {
- cout << "Derive::func1()" << endl;
- }
- virtual void func3()
- {
- cout << "Derive::func3()" << endl;
- }
- virtual void func4()
- {
- cout << "Derive::func4()" << endl;
- }
- private:
- int _d;
- };
- void PrintVfptr(int* vptr)
- //打印虚函数表
- {
- cout << "虚函数表: " << vptr << endl;
- for (int i = 0; vptr[i] != 0; ++i)
- {
- printf("第%d个虚函数:%p >> ", i, vptr[i]);
- FUNC f = (FUNC)(vptr[i]);
- f();
- }
- }
- void Test()
- {
- Base b;
- Derive d;
- int* vptrBase = (int*)(*(int*)(&b));
- int* vptrDeri = (int*)(*(int*)(&d));
- PrintVfptr(vptrBase);
- cout << endl;
- PrintVfptr(vptrDeri);
- }
- int main()
- {
- Test();
- system("pause");
- return 0;
- }
#include <iostream> using namespace std; typedef void(*FUNC)(); class Base { public: virtual void func1() { cout << "Base::func1()" << endl; } virtual void func2() { cout << "Base::func2()" << endl; } private: int _b; }; class Derive :public Base { public: virtual void func1() { cout << "Derive::func1()" << endl; } virtual void func3() { cout << "Derive::func3()" << endl; } virtual void func4() { cout << "Derive::func4()" << endl; } private: int _d; }; void PrintVfptr(int* vptr) //打印虚函数表 { cout << "虚函数表: " << vptr << endl; for (int i = 0; vptr[i] != 0; ++i) { printf("第%d个虚函数:%p >> ", i, vptr[i]); FUNC f = (FUNC)(vptr[i]); f(); } } void Test() { Base b; Derive d; int* vptrBase = (int*)(*(int*)(&b)); int* vptrDeri = (int*)(*(int*)(&d)); PrintVfptr(vptrBase); cout << endl; PrintVfptr(vptrDeri); } int main() { Test(); system("pause"); return 0; }
程序运行结果:
Base类(基类)的虚函数表:
Derive类(派生类)的虚函数表:
结论:
如果有虚函数表,那么只有一个虚函数表,并且按照虚函数声明的顺序顺序排列,派生类的虚函数紧接着基类的虚函数排列。
多继承中的虚函数表分析:
示例代码:
- #include <iostream>
- using namespace std;
- typedef void(*FUNC)();
- class Base
- {
- public:
- virtual void func1() = 0;
- virtual void func2() = 0;
- };
- class Base1:public Base
- {
- public:
- virtual void func1()
- {
- cout << "Base1::func1()" << endl;
- }
- virtual void func2()
- {
- cout << "Base1::func2()" << endl;
- }
- private:
- int _b1;
- };
- class Base2: public Base
- {
- public:
- virtual void func1()
- {
- cout << "Base2::func1()" << endl;
- }
- virtual void func2()
- {
- cout << "Base2::func2()" << endl;
- }
- private:
- int _b2;
- };
- class Derive : public Base1, public Base2
- {
- public:
- virtual void func1()
- {
- cout << "Derive::func1()" << endl;
- }
- virtual void func3()
- {
- cout << "Derive::func3()" << endl;
- }
- virtual void func4()
- {
- cout << "Derive::func4()" << endl;
- }
- private:
- int _d;
- };
- void PrintVfptr(Base* b)
- {
- int* vTable1 = (int*)(*(int*)b);
- cout << "虚函数表指针:" << vTable1 << endl;
- for (int i = 0; vTable1[i] != 0; ++i)
- {
- printf("第%d个虚函数指针: %p >>", i, vTable1[i]);
- FUNC f = (FUNC)vTable1[i];
- f();
- }
- //int* vTable2 = (int*)(*((int*)b + sizeof(Base1) / 4));
- int* vTable2 = (int*)(*((int*)((char*)b + sizeof(Base1))));
- cout << "虚函数表指针:" << vTable2 << endl;
- for (int i = 0; vTable2[i] != 0; ++i)
- {
- printf("第%d个虚函数指针: %p >>", i, vTable2[i]);
- FUNC f = (FUNC)vTable2[i];
- f();
- }
- }
- void Test()
- {
- Base1 b1;
- Base2 b2;
- Derive d;
- PrintVfptr(&b1);
- cout << endl;
- PrintVfptr(&b2);
- cout << endl;
- PrintVfptr((Base1*)&d);
- }
- int main()
- {
- Test();
- system("pause");
- return 0;
- }
#include <iostream> using namespace std; typedef void(*FUNC)(); class Base { public: virtual void func1() = 0; virtual void func2() = 0; }; class Base1:public Base { public: virtual void func1() { cout << "Base1::func1()" << endl; } virtual void func2() { cout << "Base1::func2()" << endl; } private: int _b1; }; class Base2: public Base { public: virtual void func1() { cout << "Base2::func1()" << endl; } virtual void func2() { cout << "Base2::func2()" << endl; } private: int _b2; }; class Derive : public Base1, public Base2 { public: virtual void func1() { cout << "Derive::func1()" << endl; } virtual void func3() { cout << "Derive::func3()" << endl; } virtual void func4() { cout << "Derive::func4()" << endl; } private: int _d; }; void PrintVfptr(Base* b) { int* vTable1 = (int*)(*(int*)b); cout << "虚函数表指针:" << vTable1 << endl; for (int i = 0; vTable1[i] != 0; ++i) { printf("第%d个虚函数指针: %p >>", i, vTable1[i]); FUNC f = (FUNC)vTable1[i]; f(); } //int* vTable2 = (int*)(*((int*)b + sizeof(Base1) / 4)); int* vTable2 = (int*)(*((int*)((char*)b + sizeof(Base1)))); cout << "虚函数表指针:" << vTable2 << endl; for (int i = 0; vTable2[i] != 0; ++i) { printf("第%d个虚函数指针: %p >>", i, vTable2[i]); FUNC f = (FUNC)vTable2[i]; f(); } } void Test() { Base1 b1; Base2 b2; Derive d; PrintVfptr(&b1); cout << endl; PrintVfptr(&b2); cout << endl; PrintVfptr((Base1*)&d); } int main() { Test(); system("pause"); return 0; }
程序运行结果:
Base1的虚函数表:
Base2的虚函数表:
Derive的虚函数表:(有两个虚函数表)
多继承中的菱形继承:
示例代码:
- #include <iostream>
- using namespace std;
- typedef void(*FUNC)();
- class Base
- {
- public:
- virtual void func1()
- {
- cout << "Base::func1()" << endl;
- }
- virtual void func2()
- {
- cout << "Base::func2()" << endl;
- }
- private:
- int _b;
- };
- class Parent1 :public Base
- {
- public:
- virtual void func1()
- {
- cout << "Parent1::func1()" << endl;
- }
- virtual void func3()
- {
- cout << "Parent1::func3()" << endl;
- }
- virtual void func4()
- {
- cout << "Parent1::func4()" << endl;
- }
- virtual void func5()
- {
- cout << "Parent1::func5()" << endl;
- }
- private:
- int _p1;
- };
- class Parent2 :public Base
- {
- public:
- virtual void func1()
- {
- cout << "Parent2::func1()" << endl;
- }
- virtual void func3()
- {
- cout << "Parent2::func3()" << endl;
- }
- virtual void func6()
- {
- cout << "Parent2::func6()" << endl;
- }
- virtual void func7()
- {
- cout << "Parent2::func7()" << endl;
- }
- private:
- int _p2;
- };
- class Child :public Parent1, public Parent2
- {
- public:
- virtual void func1()
- {
- cout << "Child::func1()" << endl;
- }
- virtual void func3()
- {
- cout << "Child::func3()" << endl;
- }
- virtual void func4()
- {
- cout << "Child::func4()" << endl;
- }
- virtual void func6()
- {
- cout << "Child::func6()" << endl;
- }
- virtual void func8()
- {
- cout << "Child::func8()" << endl;
- }
- private:
- int _c;
- };
- void PrintVfptr(int* vptr)
- //打印虚函数表
- {
- cout << "虚函数表: " << vptr << endl;
- for (int i = 0; vptr[i] != 0; ++i)
- {
- printf("第%d个虚函数:%p >> ", i, vptr[i]);
- FUNC f = (FUNC)(vptr[i]);
- f();
- }
- }
- void Test()
- {
- Base b;
- Parent1 p1;
- Parent2 p2;
- Child c;
- int* vptr_B = (int*)(*(((int*)(&b))));
- int* vptr_P1 = (int*)(*(((int*)(&p1))));
- int* vptr_P2= (int*)(*(((int*)(&p2))));
- PrintVfptr(vptr_B);
- cout << endl;
- PrintVfptr(vptr_P1);
- cout << endl;
- PrintVfptr(vptr_P2);
- cout << endl;
- int* vptr_C_1 = (int*)(*(((int*)(&c))));
- int* vptr_C_2 = (int*)(*(int*)((char*)(&c) + sizeof(Parent1)));
- PrintVfptr(vptr_C_1);
- cout << endl;
- PrintVfptr(vptr_C_2);
- cout << endl;
- }
- int main()
- {
- Test();
- system("pause");
- return 0;
- }
#include <iostream> using namespace std; typedef void(*FUNC)(); class Base { public: virtual void func1() { cout << "Base::func1()" << endl; } virtual void func2() { cout << "Base::func2()" << endl; } private: int _b; }; class Parent1 :public Base { public: virtual void func1() { cout << "Parent1::func1()" << endl; } virtual void func3() { cout << "Parent1::func3()" << endl; } virtual void func4() { cout << "Parent1::func4()" << endl; } virtual void func5() { cout << "Parent1::func5()" << endl; } private: int _p1; }; class Parent2 :public Base { public: virtual void func1() { cout << "Parent2::func1()" << endl; } virtual void func3() { cout << "Parent2::func3()" << endl; } virtual void func6() { cout << "Parent2::func6()" << endl; } virtual void func7() { cout << "Parent2::func7()" << endl; } private: int _p2; }; class Child :public Parent1, public Parent2 { public: virtual void func1() { cout << "Child::func1()" << endl; } virtual void func3() { cout << "Child::func3()" << endl; } virtual void func4() { cout << "Child::func4()" << endl; } virtual void func6() { cout << "Child::func6()" << endl; } virtual void func8() { cout << "Child::func8()" << endl; } private: int _c; }; void PrintVfptr(int* vptr) //打印虚函数表 { cout << "虚函数表: " << vptr << endl; for (int i = 0; vptr[i] != 0; ++i) { printf("第%d个虚函数:%p >> ", i, vptr[i]); FUNC f = (FUNC)(vptr[i]); f(); } } void Test() { Base b; Parent1 p1; Parent2 p2; Child c; int* vptr_B = (int*)(*(((int*)(&b)))); int* vptr_P1 = (int*)(*(((int*)(&p1)))); int* vptr_P2= (int*)(*(((int*)(&p2)))); PrintVfptr(vptr_B); cout << endl; PrintVfptr(vptr_P1); cout << endl; PrintVfptr(vptr_P2); cout << endl; int* vptr_C_1 = (int*)(*(((int*)(&c)))); int* vptr_C_2 = (int*)(*(int*)((char*)(&c) + sizeof(Parent1))); PrintVfptr(vptr_C_1); cout << endl; PrintVfptr(vptr_C_2); cout << endl; } int main() { Test(); system("pause"); return 0; }
运行结果:
总结:多继承中会有多个虚函数表,几重继承就会有几个虚函数表。这些虚函数表会按照派生的顺序依次排列。如果子类改写了父类的虚函数,那么就会用子类自己的虚函数覆盖相应的父类虚函数;如果子类有新的虚函数,那么就添加到第一个虚函数表的末尾。