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