菱形继承 && 虚继承

举报
芒果_Mango 发表于 2022/07/31 23:32:35 2022/07/31
【摘要】 复杂的菱形继承及菱形虚拟继承单继承:一个子类只有一个直接父类时称这个继承关系为单继承多继承:一个子类有两个或以上直接父类时称这个继承关系为多继承,用,分隔 多继承的坑: 菱形继承:菱形继承是多继承的一种特殊情况。有多继承就可能导致菱形继承,会导致问题:数据冗余二义性例子//基类class Person{public: string _name; };class Student : p...

复杂的菱形继承及菱形虚拟继承

单继承:一个子类只有一个直接父类时称这个继承关系为单继承

image-20220311211657847

多继承:一个子类有两个或以上直接父类时称这个继承关系为多继承,用,分隔 image-20220311211707047

多继承的坑: 菱形继承:菱形继承是多继承的一种特殊情况。

image-20220311211721737

有多继承就可能导致菱形继承,会导致问题:

  • 数据冗余
  • 二义性

例子

//基类
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; 
};

int main()
{
    Assistant a;
    a._name = "peter"; //导致二义性:无法明确知道要访问哪一个_name
    return 0;
}

image-20220313095735105


菱形继承的问题:从下面的对象成员模型构造,可以看出菱形继承有数据冗余和二义性的问题。在Assistant 的对象中Person成员会有两份。


解决办法1:显示指定作用域去访问

int main()
{
    Assistant a;
    //指定哪个父类的成员
    a.Teacher::_name = "Mango";
    a.Student::_name = "Lemon";
    return 0;
}

image-20220313100015787

虽然这样可以解决二义性的问题,但是不能解决数据冗余的问题


虚继承

C++不能容忍数据冗余和二义性,提出了新的解决方案, 虚继承:新的关键字:virtual

虚拟继承可以解决菱形继承的二义性和数据冗余的问题。

如上面的继承关系,在Student和Teacher的继承Person时使用虚拟继承,即可解决问题。需要注意的是,虚拟继承不要在其他地方去使用。

image-20220313100550236


//基类
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;
};
int main()
{
    Assistant a;
    //虚继承之后,可以解决数据冗余和二义性的问题
    a._name = "Mango";
    return 0;
}

image-20220313100756430

此时我们可以直接访问_name成员,并且都是同一个结果,解决了二义性的问题。

我们打印Assistant的Student父类和Teacher父类的_name成员的地址时,显示的也是同一个地址,解决了数据冗余的问题。

//二者地址相同,解决了数据冗余的问题
cout << &a.Student::_name << endl; 
cout << &a.Teacher::_name << endl;

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。