菱形继承
类AA被类BB和类CC重复继承:
class AA
{
public:
virtual void a(){ cout << "AA::a()" << endl; }
virtual void a1(){ cout << "AA::a1()" << endl; }
public:
int _a;
};
class BB : public AA
{
public:
virtual void a(){ cout << "BB::a()" << endl; }
virtual void a2(){ cout << "BB::a2()" << endl; }
virtual void a3(){ cout << "BB::a3()" << endl; }
public:
int _b;
};
class CC : public AA
{
public:
virtual void a(){ cout << "CC::a()" << endl; }
virtual void a1(){ cout << "CC::a1()" << endl; }
virtual void a4(){ cout << "CC::a4()" << endl; }
public:
int _c;
};
class DD : public BB , public CC
{
public:
virtual void a(){ cout << "DD::a()" << endl; }
virtual void a2(){ cout << "DD::a2()" << endl; }
virtual void a3(){ cout << "DD::a3()" << endl; }
virtual void a5(){ cout << "DD::a5()" << endl; }
public:
int _d;
};
typedef void(*FUNC) ();
void Print(int *Vfptr)
{
cout << "虚表地址" << Vfptr << endl;
for (int i = 0; Vfptr[i] != 0; ++i)
{
FUNC f = (FUNC)Vfptr[i];
cout << "[" << i << "]" << endl;
f();
}
cout << endl;
}
int main()
{
DD d;
int *Vfptr1 = (int*)(*(int*)&d);
int *Vfptr2 = (int*)(*((int*)&d+sizeof(BB)/4));
Print(Vfptr1);
Print(Vfptr2);
system("pause");
return 0;
}
虚表的结果:
菱形继承总结:
会出现数据冗余和二义性问题
派生类会分别继承每个基类的虚函数表,并将自己的虚函数放在第一个虚函数表中
成员变量的顺序按照继承的关系排列
菱形虚拟继承
虚继承就是在类BB和类CC继承的时候加上virtual关键字
class AA
{
public:
virtual void a(){ cout << "AA::a()" << endl; }
virtual void a1(){ cout << "AA::a1()" << endl; }
public:
int _a;
};
class BB : virtual public AA
{
public:
virtual void a(){ cout << "BB::a()" << endl; }
virtual void a2(){ cout << "BB::a2()" << endl; }
virtual void a3(){ cout << "BB::a3()" << endl; }
public:
int _b;
};
class CC : virtual public AA
{
public:
virtual void a(){ cout << "CC::a()" << endl; }
virtual void a1(){ cout << "CC::a1()" << endl; }
virtual void a4(){ cout << "CC::a4()" << endl; }
public:
int _c;
};
class DD : public BB , public CC
{
public:
virtual void a(){ cout << "DD::a()" << endl; }
virtual void a2(){ cout << "DD::a2()" << endl; }
virtual void a3(){ cout << "DD::a3()" << endl; }
virtual void a5(){ cout << "DD::a5()" << endl; }
public:
int _d;
};
typedef void(*FUNC) ();
void Print(int *Vfptr)
{
cout << "虚表地址" << Vfptr << endl;
for (int i = 0; Vfptr[i] != 0; ++i)
{
FUNC f = (FUNC)Vfptr[i];
cout << "[" << i << "]" << endl;
f();
}
cout << endl;
}
int main()
{
DD d;
int *Vfptr1 = (int*)(*(int*)&d);
int *Vfptr2 = (int*)(*(int*)((char*)&d+sizeof(DD)-sizeof(AA)));
int *Vfptr3 = (int*)(*((int*)((char*)&d + sizeof(BB)-sizeof(AA))));
Print(Vfptr1);
Print(Vfptr2);
Print(Vfptr3);
system("pause");
return 0;
}
注:当类BB,类CC都对类AA中的虚函数a()进行覆盖,会编译出错,出现二义性问题。这时类DD需要对虚函数a()进行重写,才可避免。