cpp——类——VBTBL

来源:互联网 发布:xbox软件是什么 编辑:程序博客网 时间:2024/06/06 14:23

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) = 16animal vptr addr = 0x7fff5fbff740animal vtbl addr = 0x1000020e0animal feed addr = 0x100001180animal work addr = 0x1000011d0CAnimal::feed()CAnimal::work()sizeof(dog) = 24dog vptr addr = 0x7fff5fbff718dog vtbl addr = 0x100002118dog feed addr = 0x0dog work addr = 0x0dog vbptr addr = 0x7fff5fbff720dog vbtbl addr = 0x100002138dog feed addr = 0x100001180dog work addr = 0x1000011d0CAnimal::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) = 16animal vptr addr = 0x7fff5fbff740animal vtbl addr = 0x1000020e0animal feed addr = 0x1000010a0animal work addr = 0x1000010f0CAnimal::feed()CAnimal::work()sizeof(dog) = 24dog vptr addr = 0x7fff5fbff718dog vtbl addr = 0x100002118dog feed addr = 0x100001140dog work addr = 0x100001190CDog::watch()CDog::work()dog vbptr addr = 0x7fff5fbff720dog vbtbl addr = 0x100002148dog feed addr = 0x1000010a0dog work addr = 0x1000011e0CAnimal::feed()CDog::work()

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

多继承

子类不更新

子类更新