菱形继承
定义及形式
简单的理解就是同一个父类被两个不同子类继承,而这两个子类又被另一个新类同时继承,导致出现了一个类似菱形的继承体系,我们将其成为菱形继承。
关于菱形继承的其他解释,我在上一博客中做了介绍(http://blog.csdn.net/haitang_yue/article/details/55211296),这里不做赘述。普通菱形继承
- 代码
typedef void (*V_FUNC)();
class AA
{
public:
virtual void f1()
{
cout<<"AA::f1"<<endl;
}
public:
int _aa;
};
class BB:virtual public AA
{
public:
virtual void f1()
{
cout<<"BB::f1"<<endl;
}
virtual void f2()
{
cout<<"BB::f2"<<endl;
}
public:
int _bb;
};
class CC:virtual public AA
{
public:
virtual void f1()
{
cout<<"CC::f1"<<endl;
}
virtual void f2()
{
cout<<"CC::f2"<<endl;
}
public:
int _cc;
};
class DD:public BB,public CC
{
public:
virtual void f1()
{
cout<<"DD::f1"<<endl;
}
virtual void f3()
{
cout<<"DD::f2"<<endl;
}
virtual void f4()
{
cout<<"DD::f4"<<endl;
}
public:
int _dd;
};
void PrintVTable (int* VTable)
{
cout<<" 虚表地址>0x"<< VTable<<endl ;
for (int i = 0; VTable[i ] != 0; ++i)
{
V_FUNC f = (V_FUNC) VTable[i];
f();
}
cout<<endl ;
}
int main()
{
DD d;
d.BB::_aa = 0;
d.CC::_aa = 1;
d._bb = 2;
d._cc = 3;
d._dd = 4;
cout<<"DD";
int* VTable = (int*)(*(int*)&d );
PrintVTable(VTable);
cout<<"DD-CC";
VTable = (int*)(*((int*)&d+3) );
PrintVTable(VTable);
cout<<"DD-AA";
VTable = (int*)(*((int*)&d+7));
PrintVTable(VTable);
system("pause");
return 0;
}
- DD类对象模型
- 对普通菱形继承时虚表的分析
- 内存中的情况:
由于有两个父类,所以存在两个虚表
菱形虚拟继承
- 简介
为了解决菱形继承中二义性以及数据冗余所带来的缺点,通过使用虚拟继承用空间换时间的思想来解决问题。不过应注意,在我们平时的代码编写中,不到万不得已时最好不要使用菱形继承以及虚继承,因为这种结构所带来的效率问题很多。 - 代码
class AA
{
public:
virtual void f1()
{
cout<<"AA::f1"<<endl;
}
public:
int _aa;
};
class BB:virtual public AA
{
public:
virtual void f1()
{
cout<<"BB::f1"<<endl;
}
virtual void f2()
{
cout<<"BB::f2"<<endl;
}
public:
int _bb;
};
class CC:virtual public AA
{
public:
virtual void f1()
{
cout<<"CC::f1"<<endl;
}
virtual void f3()
{
cout<<"CC::f3"<<endl;
}
public:
int _cc;
};
class DD:public BB,public CC
{
public:
virtual void f1()
{
cout<<"DD::f1"<<endl;
}
virtual void f3()
{
cout<<"DD::f3"<<endl;
}
virtual void f4()
{
cout<<"DD::f4"<<endl;
}
public:
int _dd;
};
typedef void (*V_FUNC)();
void PrintVTable(int* VTable)
{
cout<<"虚表地址>0x"<< VTable<<endl ;
for (int i=0;VTable[i]!=0;++i)
{
V_FUNC f=(V_FUNC)VTable[i];
f();
}
cout<<endl ;
}
int main()
{
DD d;
d._aa = 1;
d._bb = 1;
d._cc = 1;
d._dd = 1;
cout<<"DD";
int* VTable = (int*)(*(int*)&d );
PrintVTable(VTable);
cout<<"DD-CC";
VTable = (int*)(*((int*)&d+3) );
PrintVTable(VTable);
cout<<"DD-AA";
VTable = (int*)(*((int*)&d+7));
PrintVTable(VTable);
system("pause");
return 0;
}
运行结果
内存分析