复杂的菱形继承及菱形虚拟继承
一、单继承
一个子类只有一个直接父类时称这个继承关系为单继承,如图:
二、多继承
一个子类有两个或以上直接父类时称这个继承关系为多继承,如图:
三、菱形继承
如图所示:
1.数据冗余和二义性
菱形继承会有数据冗余和二义性的问题。
代码示例:
class Person
{
public :
string _name ; // 姓名
};
class Student : public Person
{
protected :
int _num ; //学号
};
class Teacher : public Person
{
protected :
int _id ; // 职工编号
};
class Assistant : public Student, public Teacher
{
protected :
string _majorCourse ; // 主修课程
};
void Test ()
{
// 这样会有二义性无法明确知道访问的是哪一个
Assistant a ;
a._name = "peter";
// 需要显示指定访问哪个父类的成员可以解决二义性问题,但是数据冗余问题无法解决
a.Student::_name = "xxx";
a.Teacher::_name = "yyy"; }
此时, Assistant的对象中,penson成员会有两份。
2.解决方案:虚拟继承
虚拟继承可以解决菱形继承的二义性和数据冗余的问题。如上面的继承关系,在Student和Teacher的继承
Person时使用虚拟继承。
需要注意的是,虚拟继承不要在其他地方去使用。
代码示例:
class Person
{
public :
string _name ; // 姓名
};
class Student : virtual public Person
{
protected :
int _num ; //学号
};
class Teacher : virtual public Person
{
protected :
int _id ; // 职工编号
};
class Assistant : public Student, public Teacher
{
protected :
string _majorCourse ; // 主修课程
};
void Test ()
{
Assistant a ;
a._name = "peter";
}
四、总结
- 有了多继承,就存在菱形继承,有了菱形继承就有菱形虚拟继承,底层实现就很复杂。所以一般不建议设计出多继承,一定不要设计出菱形继承。否则在
复杂度及性能上都有问题。 - 多继承可以认为是C++的缺陷之一