理解虚基类和虚继承
- 抽象类:有纯虚函数的类。而虚基类是被虚继承的类。
class B: virtual public A
- 如果是普通继承,B对象内存开头存储基类A的成员,后接B的独有成员。
- 虚继承后B对象内存开头存储一个vbptr(virtual base ptr),指向一个vbtable,vbtable存储两个偏移量,第一个偏移量是vbptr在B内存的偏移量,即0;第二个偏移量是基类A的成员在B中的偏移量。
- 再次深入理解虚函数表
class A
{
};
class B
{
virtual void func(){}
};
class C : virtual public B
{
};
int main()
{
cout << sizeof(A) <<sizeof(B) <<sizeof(C); //1 8:vfptr(vftable) 16:vbptr(vbtable)
}
#include <iostream>
using namespace std;
class A
{
public:
virtual void func() { cout << "call A::func()" << endl; }
private:
int ma;
};
class B : virtual public A
{
public:
virtual void func() { cout << "call B::func()" << endl; }
private:
int mb;
};
int main()
{
// 基类指针指向派生类对象,永远指向的是派生类基类部分数据的起始地址
//即p指向的是基类A中的vfptr(虚函数表指针)及基类成员
//事实上,vfptr只有一个,派生类所使用的就是基类中的vfptr,只不过经过了重写覆盖
//vftable中,上面是基类虚函数,下面是派生类的虚函数,如果是重写,则在基类虚函数上覆盖
A* p = new B();
p->func();
//下方的内存回收会出问题,vbptr以及派生类独有对象没有正确释放
delete p;
return 0;
}