菱形虚拟继承的模式
class A;
class B : virtual public A;
class C : virtual public A;
class D : public B , public c;
单一的虚拟继承
引例一:
class Base
{
private:
int _a;
};
class Derived : virtual public Base
{
};
sizeof(Base)=?
sizeof(Derived)=?
虚拟继承时,在派生类的对象内存中会产生一个指向虚基表的指针,所以
sizeof(Base )=4; sizeof(Base ) = _a;
sizeof(Derived )=8; sizeof(Derived ) =_a + Derived 中的指向虚基表的指针;
引例二:
class Base
{
public:
virtual void funl()
{
cout << "Base::fun1()" << endl;
}
private:
int _a;
};
class Derived : virtual public Base
{
public:
virtual void funl()
{
cout << "Derived::fun1()" << endl;
}
virtual void Derivedfun2()
{
cout << "Derived::Derivedfun2()" << endl;
}
};
sizeof(Base)=?
sizeof(Derived)=?
虚基类的虚表指针是不会被派生类所共享的,若派生类中含有新的虚函数(改写的不算),将会自己产生一个指向自己虚表的指针
sizeof(Base) =_a + Base 中 指向 虚函数表的指针
sizeof(Base) =8;
sizeof(Derived ) =Derived 的虚函数表指针 + Derived 中的指向虚基表的指针 + Base的虚函数表指针+_a
sizeof(Derived) =16;
菱形虚拟继承
#include<iostream>
using namespace std;
class Base
{
public:
virtual void func1()
{
cout << "Base::func1()" << endl;
}
virtual void Basefunc2()
{
cout << "Base::func2()" << endl;
}
private:
int b;
};
class Base1 :public virtual Base
{
public:
virtual void func1()
{
cout << "Base1::func1()" << endl;
}
virtual void Base1func2()
{
cout << "Base1::func2()" << endl;
}
private:
int b1;
};
class Base2 :public virtual Base
{
public:
virtual void func1()
{
cout << "Base2::func1()" << endl;
}
virtual void Base2func2()
{
cout << "Base2::func2()" << endl;
}
private:
int b2;
};
typedef void (*FUNC)();
void PrintVTable(int *VTable)
{
cout << "虚表地址:" << VTable << endl;
for (int i = 0; VTable[i] != 0; i++)
{
printf( "第VTable[%d]是:OX%x->" , i, VTable[i]);
FUNC p = (FUNC )VTable[i];
p();
}
cout << endl;
}
class Derived : public Base1, public Base2
{
public:
virtual void func1()
{
cout << "Derived::func1()" << endl;
}
virtual void Derivedfunc2()
{
cout << "Derived::func2()" << endl;
}
virtual void Derivedfunc3()
{
cout << "Derived::func3()" << endl;
}
private:
int d1;
};
1. cout << sizeof(Base) << endl;
Base中指向虚函数表的指针 + b
2. cout << sizeof(Base1) << endl;
Base1中指向虚函数表的指针 + Base1 中指向虚基类表的指针 + b1 + Base 中指向虚函数表的指针 + b
3. cout << sizeof(Base2) << endl;
Base2中指向它虚函数表的指针 + Base2 中指向虚基类表的指针 + b2 + Base 中指向它虚函数表的指针 + b
4. cout << sizeof(Derived) << endl;
Base1中指向它虚函数表的指针 + Base1 中指向虚基类表的指针 + b1
+ Base2中指向它虚函数表的指针 + Base2 中指向虚基类表的指针 + b2
+ d1
+ Base 中指向虚函数表的指针 + b
Base的对象b:
Base b;
int *VTable = (int *)(*(int *)&b);
PrintVTable(VTable); //Base的虚函数表
Base1的对象b1:
(1) //Base1的虚函数表,即_vptr_B1的指向
Base1 b1;
int *VTable = (int *)*(int *)&b1;
PrintVTable(VTable);
(2) //Base的虚函数表
VTable = ( int *)*(int *)((char *)&b1 + sizeof(Base1 )-sizeof( Base)); //看Base1的对象的内存布局
PrintVTable(VTable);
(3) 虚基表里的内容
(a). b1的地址相对于_vbptr的地址的偏移量(即看Base1里有无 _vptr_B1) ;
(b). Base的 _vptr_B 的地址相对于 _vbptr 的地址的偏移量;
运行查看虚基类表里的内容:
(a) : cout<<*((int *)(*((int *)(&b1) + 1)))<<endl;
(b) : cout<<*((int *)(*(( int *)(&b1) + 1))+1)<<endl;
Base2与Base1情况一样
Derived的对象d1:
(1) //Base1的虚函数表,即_vptr_B1的指向
int* VTable = (int *)*(int *)&d1;
PrintVTable(VTable);
(2)//Base2的虚函数表,即_vptr_B2的指向
VTable = ( int *)*(int *)((char *)&d1 + sizeof(Base1 )-sizeof( Base));
PrintVTable(VTable);
(3)//Base的虚函数表,即_vptr_B的指向
VTable = ( int *)*(int *)((char *)&d1 + sizeof(Derived )-sizeof( Base));
PrintVTable(VTable);