cpp——类——VBTBL

VBTBL

VBTBL,virtual base table,即虚基类表,如果子类虚继承父类,就会生成VBTBL,VBTBL包含类的新增virtual成员函数入口地址,包含VBTBL的类,包含字段vbptr指针,指向类的VBTBL,因此VBTBL被所有类实例对象所共享
子类会继承父类的VBTBL,也会继承父类的vbptr指针,并初始化为指向子类VBTBL
注:某些IDE中,比如xcode,如果虚基类无自定义字段(vptr除外),则vptr和vbptr共享同一指针字段,VTBL和VBTBL也自然共享同一TBL,vs中如果虚基类无自定义字段(vptr除外),vptr和vbptr不会共享同一指针字段,VTBL和VBTBL也自然不会共享同一TBL

单继承

子类不更新

class CAnimal
{
public:
    virtual void feed()
    {
        cout << "CAnimal::feed()" << endl;
    }
    
    virtual void work()
    {
        cout << "CAnimal::work()" << endl;
    }
    
private:
    int mGroup;
};

class CDog : virtual public CAnimal
{
};

typedef void (*PVM)();

void vbtbl()
{
    CAnimal animal;
    cout << "sizeof(animal) = " << sizeof(animal) << endl;
    cout << "animal vptr addr = " << (long*)&animal << endl;
    cout << "animal vtbl addr = " << (long*)*(long*)&animal << endl;
    cout << "animal feed addr = " << (long*)*((long*)*(long*)&animal) << endl;
    cout << "animal work addr = " << (long*)*((long*)*(long*)&animal + 1) << endl;
    PVM animal_vm1 = (PVM)(long*)*(long*)*(long*)&animal;
    PVM animal_vm2 = (PVM)(long*)*((long*)*(long*)&animal + 1);
    animal_vm1();
    animal_vm2();
    
    CDog dog;
    cout << "sizeof(dog) = " << sizeof(dog) << endl;
    cout << "dog vptr addr = " << (long*)&dog << endl;
    cout << "dog vtbl addr = " << (long*)*(long*)&dog << endl;
    cout << "dog feed addr = " << (long*)*((long*)*(long*)&dog) << endl;
    cout << "dog work addr = " << (long*)*((long*)*(long*)&dog + 1) << endl;
    //PVM dog_vm1 = (PVM)(long*)*(long*)*(long*)&dog;
    //PVM dog_vm2 = (PVM)(long*)*((long*)*(long*)&dog + 1);
    //dog_vm1();
    //dog_vm2();
    
    cout << "dog vbptr addr = " << (long*)&dog + 1 << endl;
    cout << "dog vbtbl addr = " << (long*)*((long*)&dog + 1) << endl;
    cout << "dog feed addr = " << (long*)*((long*)*((long*)&dog + 1)) << endl;
    cout << "dog work addr = " << (long*)*((long*)*((long*)&dog + 1) + 1) << endl;
    PVM dog_vb_vm1 = (PVM)(long*)*(long*)*((long*)&dog + 1);
    PVM dog_vb_vm2 = (PVM)(long*)*((long*)*((long*)&dog + 1) + 1);
    dog_vb_vm1();
    dog_vb_vm2();
}
output:
sizeof(animal) = 16
animal vptr addr = 0x7fff5fbff740
animal vtbl addr = 0x1000020e0
animal feed addr = 0x100001180
animal work addr = 0x1000011d0
CAnimal::feed()
CAnimal::work()
sizeof(dog) = 24
dog vptr addr = 0x7fff5fbff718
dog vtbl addr = 0x100002118
dog feed addr = 0x0
dog work addr = 0x0
dog vbptr addr = 0x7fff5fbff720
dog vbtbl addr = 0x100002138
dog feed addr = 0x100001180
dog work addr = 0x1000011d0
CAnimal::feed()
CAnimal::work()
总结:
  • 如果包含vptr字段,vbptr字段位于vptr字段之后,否则vbptr字段为第一个字段
  • VBTBL内容为父类VTBL

子类更新

class CAnimal
{
public:
    virtual void feed()
    {
        cout << "CAnimal::feed()" << endl;
    }
    
    virtual void work()
    {
        cout << "CAnimal::work()" << endl;
    }
    
private:
    int mGroup;
};

class CDog : virtual public CAnimal
{
public:
    virtual void watch()
    {
        cout << "CDog::watch()" << endl;
    }
    
    virtual void work()
    {
        cout << "CDog::work()" << endl;
    }
};

typedef void (*PVM)();

void vbtbl()
{
    CAnimal animal;
    cout << "sizeof(animal) = " << sizeof(animal) << endl;
    cout << "animal vptr addr = " << (long*)&animal << endl;
    cout << "animal vtbl addr = " << (long*)*(long*)&animal << endl;
    cout << "animal feed addr = " << (long*)*((long*)*(long*)&animal) << endl;
    cout << "animal work addr = " << (long*)*((long*)*(long*)&animal + 1) << endl;
    PVM animal_vm1 = (PVM)(long*)*(long*)*(long*)&animal;
    PVM animal_vm2 = (PVM)(long*)*((long*)*(long*)&animal + 1);
    animal_vm1();
    animal_vm2();
    
    CDog dog;
    cout << "sizeof(dog) = " << sizeof(dog) << endl;
    cout << "dog vptr addr = " << (long*)&dog << endl;
    cout << "dog vtbl addr = " << (long*)*(long*)&dog << endl;
    cout << "dog feed addr = " << (long*)*((long*)*(long*)&dog) << endl;
    cout << "dog work addr = " << (long*)*((long*)*(long*)&dog + 1) << endl;
    PVM dog_vm1 = (PVM)(long*)*(long*)*(long*)&dog;
    PVM dog_vm2 = (PVM)(long*)*((long*)*(long*)&dog + 1);
    dog_vm1();
    dog_vm2();
    
    cout << "dog vbptr addr = " << (long*)&dog + 1 << endl;
    cout << "dog vbtbl addr = " << (long*)*((long*)&dog + 1) << endl;
    cout << "dog feed addr = " << (long*)*((long*)*((long*)&dog + 1)) << endl;
    cout << "dog work addr = " << (long*)*((long*)*((long*)&dog + 1) + 1) << endl;
    PVM dog_vb_vm1 = (PVM)(long*)*(long*)*((long*)&dog + 1);
    PVM dog_vb_vm2 = (PVM)(long*)*((long*)*((long*)&dog + 1) + 1);
    dog_vb_vm1();
    dog_vb_vm2();
}

output:
sizeof(animal) = 16
animal vptr addr = 0x7fff5fbff740
animal vtbl addr = 0x1000020e0
animal feed addr = 0x1000010a0
animal work addr = 0x1000010f0
CAnimal::feed()
CAnimal::work()
sizeof(dog) = 24
dog vptr addr = 0x7fff5fbff718
dog vtbl addr = 0x100002118
dog feed addr = 0x100001140
dog work addr = 0x100001190
CDog::watch()
CDog::work()
dog vbptr addr = 0x7fff5fbff720
dog vbtbl addr = 0x100002148
dog feed addr = 0x1000010a0
dog work addr = 0x1000011e0
CAnimal::feed()
CDog::work()

总结:
子类virtual成员函数(包括新增virtual成员函数,override virtual成员函数)构成VTBL,同时更新VBTBL

多继承

子类不更新

子类更新

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值