单继承类的虚函数表

打印虚函数表

#include <iostream>
#include <stdio.h>

using namespace std;

class ClassA
{
public:
    ClassA(){m_data1 = 1; m_data2 = 2;}
    int m_data1;
    int m_data2;

    void func1(){cout << "ClassA::func1" << endl;}
    void func2(){cout << "ClassA::func2" << endl;}
    virtual void vfunc1(){cout << "ClassA::vfunc1" << endl;}
    virtual void vfunc2(){cout << "ClassA::vfunc2" << endl;}
};

class ClassB : public ClassA
{
public:
    ClassB(){m_data3 = 3;}
    int m_data3;
    void func2(){cout << "ClassB::func2" << endl;}
    virtual void vfunc1(){cout << "ClassB::vfunc1" << endl;}
};

class ClassC : public ClassB
{
public:
    ClassC(){m_data4= 5; m_data1 = 4;}
    int m_data1;
    int m_data4;
    void func2(){cout << "ClassC::func2" << endl;}
    virtual void vfunc1(){cout << "ClassC::vfunc1" << endl;}
};

int main()
{
    ClassA a;
    ClassB b;
    ClassC c;

    long *v;    // v is the address of vptr
    long *vtbl0;    // vtbl0 is the address of vtbl[0]
    Fun pFun = nullptr;

    v = (long*)&a;
    vtbl0 = (long*)(*v);
    cout << "ClassA.vptr=" << v << " ClassA.vtbl[0]=" << vtbl0 << endl;

    for (int i = 0; i < 6; ++i)
        printf("ClassA vtbl[%d]=%#x  // %#x \n", i, *(vtbl0 + i), (vtbl0 + i));
    cout << endl;

    v = (long*)&b;
    vtbl0 = (long*)(*v);
    cout << "ClassB.vptr=" << v << " ClassB.vtbl[0]=" << vtbl0 << endl;
    for (int i = 0; i< 6; ++i)
        printf("ClassB vtbl[%d]=%#x // %#x \n", i, *(vtbl0 + i), (vtbl0+i));
    cout << endl;

    v = (long*)&c;
    vtbl0 = (long*)(*v);
    cout << "ClassC.vptr=" << v << " ClassC.vtbl[0]=" << vtbl0 << endl;
    for (int i = 0; i < 6; ++i)
        printf("ClassC vtbl[%d]=%#x // %#x \n", i, *(vtbl0 + i), (vtbl0+i));
    cout << endl;
	
	return 0;   
}

运行结果:

ClassA.vptr=0xfff656e8 ClassA.vtbl[0]=0x5664ae88
ClassA vtbl[0]=0x566491d0  // 0x5664ae88 
ClassA vtbl[1]=0x56649216  // 0x5664ae8c 
ClassA vtbl[2]=0xf7f6e0ec  // 0x5664ae90 注意:这里不是结束符
ClassA vtbl[3]=0x566496a8  // 0x5664ae94 
ClassA vtbl[4]=0x5664ae9c  // 0x5664ae98 
ClassA vtbl[5]=0xf7f6e0ec  // 0x5664ae9c 

ClassB.vptr=0xfff656f4 ClassB.vtbl[0]=0x5664ae78
ClassB vtbl[0]=0x566492de // 0x5664ae78 
ClassB vtbl[1]=0x56649216 // 0x5664ae7c 
ClassB vtbl[2]=0 // 0x5664ae80 
ClassB vtbl[3]=0x5664aea8 // 0x5664ae84 
ClassB vtbl[4]=0x566491d0 // 0x5664ae88 
ClassB vtbl[5]=0x56649216 // 0x5664ae8c 

ClassC.vptr=0xfff65704 ClassC.vtbl[0]=0x5664ae68
ClassC vtbl[0]=0x566493b0 // 0x5664ae68 
ClassC vtbl[1]=0x56649216 // 0x5664ae6c 
ClassC vtbl[2]=0 // 0x5664ae70 
ClassC vtbl[3]=0x5664ae9c // 0x5664ae74 
ClassC vtbl[4]=0x566492de // 0x5664ae78 
ClassC vtbl[5]=0x56649216 // 0x5664ae7c 

遇到问题:ClassB.vtbl[2]=0和ClassC.vtbl[2]=0,说明虚函数表的结束符应该是0,但为什么ClassA的虚函数表中又没有出现呢?
下面通过函数指针指向虚函数表的值,再调用成员函数,看虚函数表中放了什么


#include <iostream>
#include <stdio.h>

using namespace std;

class ClassA
{
public:
    ClassA(){m_data1 = 1; m_data2 = 2;}
    int m_data1;
    int m_data2;

    void func1(){cout << "ClassA::func1" << endl;}
    void func2(){cout << "ClassA::func2" << endl;}
    virtual void vfunc1(){cout << "ClassA::vfunc1" << endl;}
    virtual void vfunc2(){cout << "ClassA::vfunc2" << endl;}
};

class ClassB : public ClassA
{
public:
    ClassB(){m_data3 = 3;}
    int m_data3;
    void func2(){cout << "ClassB::func2" << endl;}
    virtual void vfunc1(){cout << "ClassB::vfunc1" << endl;}
};

class ClassC : public ClassB
{
public:
    ClassC(){m_data4= 5; m_data1 = 4;}
    int m_data1;
    int m_data4;
    void func2(){cout << "ClassC::func2" << endl;}
    virtual void vfunc1(){cout << "ClassC::vfunc1" << endl;}
};

int main()
{
    ClassA a;
    ClassB b;
    ClassC c;
    
    long *v;    // v is the address of vptr
    long *vtbl0;    // vtbl0 is the address of vtbl[0]
    Fun pFun = nullptr;

    v = (long*)&a;
    vtbl0 = (long*)(*v);
    cout << "ClassA.vptr=" << v << " ClassA.vtbl[0]=" << vtbl0 << endl;

    for (int i = 0; i < 2; ++i)
    {
        printf("ClassA vtbl[%d]=%#x  %#x \n", i, *(vtbl0 + i), (vtbl0 + i));
        pFun = (Fun)*(vtbl0+i);
        if ( *(vtbl0 + i) == 0) {cout << endl; break;}
        pFun();
    }
    cout << endl;

    v = (long*)&b;
    vtbl0 = (long*)(*v);
    cout << "ClassB.vptr=" << v << " ClassB.vtbl[0]=" << vtbl0 << endl;
    for (int i = 0; i< 6; ++i)
    {
        printf("ClassB vtbl[%d]=%#x %#x \n", i, *(vtbl0 + i), (vtbl0+i));
        pFun = (Fun)*(vtbl0+i);
        if ( *(vtbl0 + i) == 0) {cout << endl; break;}
        pFun();
    }
    cout << endl;

    v = (long*)&c;
    vtbl0 = (long*)(*v);
    cout << "ClassC.vptr=" << v << " ClassC.vtbl[0]=" << vtbl0 << endl;
    for (int i = 0; i < 6; ++i)
    {
        printf("ClassC vtbl[%d]=%#x %#x \n", i, *(vtbl0 + i), (vtbl0+i));
        pFun = (Fun)*(vtbl0+i);
        if ( *(vtbl0 + i) == 0) {cout << endl; break;}
        pFun();
    }
    cout << endl;
    
    return 0;
}

运行结果:

ClassA.vptr=0xff804738 ClassA.vtbl[0]=0x565c0e88
ClassA vtbl[0]=0x565bf2c0  0x565c0e88 ClassA::vfunc1
ClassA vtbl[1]=0x565bf306  0x565c0e8c ClassA::vfunc2

ClassB.vptr=0xff804744 ClassB.vtbl[0]=0x565c0e78
ClassB vtbl[0]=0x565bf3ce 0x565c0e78 ClassB::vfunc1 //子类override后,虚函数表也发生了变化
ClassB vtbl[1]=0x565bf306 0x565c0e7c ClassA::vfunc2
ClassB vtbl[2]=0 0x565c0e80 

ClassC.vptr=0xff804754 ClassC.vtbl[0]=0x565c0e68
ClassC vtbl[0]=0x565bf4a0 0x565c0e68 ClassC::vfunc1  //子类override后,虚函数表也发生了变化
ClassC vtbl[1]=0x565bf306 0x565c0e6c ClassA::vfunc2
ClassC vtbl[2]=0 0x565c0e70 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值