单继承与多继承中的虚函数表和虚函数指针


编译环境: VS 2013


首先,我们了解一下何为单继承,何为多继承??

单继承:一个子类只有一个直接父类。

多继承:一个子类有两个或多个直接父类。

单继承中的虚函数表分析:

示例程序:

#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类(基类)的虚函数表:

wKioL1bcEMbyJxs-AAAQf1oQ-Ns235.png

Derive类(派生类)的虚函数表:

wKiom1bcEHuxOB0QAAAcF7C983I617.png

结论:

如果有虚函数表,那么只有一个虚函数表,并且按照虚函数声明的顺序顺序排列,派生类的虚函数紧接着基类的虚函数排列


多继承中的虚函数表分析:

示例代码:

#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的虚函数表:

wKioL1bcFcSzAXRSAAAX-leGeyg336.png

Base2的虚函数表:

wKioL1bcFq2xTaMeAAAQJsD_jQU490.png

Derive的虚函数表:(有两个虚函数表)

wKioL1bcFyCAR3u_AAAq7ZbMpMs067.png

多继承中的菱形继承:

示例代码:

#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;  
}  



运行结果:

wKioL1bcGALwhph7AABvr4tJVO0897.png其中,Child有两个虚函数表,因为它有两个直接父类。


总结:多继承中会有多个虚函数表,几重继承就会有几个虚函数表。这些虚函数表会按照派生的顺序依次排列。如果子类改写了父类的虚函数,那么就会用子类自己的虚函数覆盖相应的父类虚函数;如果子类有新的虚函数,那么就添加到第一个虚函数表的末尾。






















本文转自:

https://blog.csdn.net/fucangzxx/article/details/51534117








  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值