菱形继承 && 虚继承
【摘要】 复杂的菱形继承及菱形虚拟继承单继承:一个子类只有一个直接父类时称这个继承关系为单继承多继承:一个子类有两个或以上直接父类时称这个继承关系为多继承,用,分隔 多继承的坑: 菱形继承:菱形继承是多继承的一种特殊情况。有多继承就可能导致菱形继承,会导致问题:数据冗余二义性例子//基类class Person{public: string _name; };class Student : p...
复杂的菱形继承及菱形虚拟继承
单继承:一个子类只有一个直接父类时称这个继承关系为单继承
多继承:一个子类有两个或以上直接父类时称这个继承关系为多继承,用,
分隔
多继承的坑: 菱形继承:菱形继承是多继承的一种特殊情况。
有多继承就可能导致菱形继承,会导致问题:
- 数据冗余
- 二义性
例子
//基类
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;
}
菱形继承的问题:从下面的对象成员模型构造,可以看出菱形继承有数据冗余和二义性的问题。在Assistant 的对象中Person成员会有两份。
解决办法1:显示指定作用域去访问
int main()
{
Assistant a;
//指定哪个父类的成员
a.Teacher::_name = "Mango";
a.Student::_name = "Lemon";
return 0;
}
虽然这样可以解决二义性的问题,但是不能解决数据冗余的问题
虚继承
C++不能容忍数据冗余和二义性,提出了新的解决方案, 虚继承:新的关键字:virtual
虚拟继承可以解决菱形继承的二义性和数据冗余的问题。
如上面的继承关系,在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;
};
int main()
{
Assistant a;
//虚继承之后,可以解决数据冗余和二义性的问题
a._name = "Mango";
return 0;
}
此时我们可以直接访问_name成员,并且都是同一个结果,解决了二义性的问题。
我们打印Assistant的Student父类和Teacher父类的_name成员的地址时,显示的也是同一个地址,解决了数据冗余的问题。
//二者地址相同,解决了数据冗余的问题
cout << &a.Student::_name << endl;
cout << &a.Teacher::_name << endl;
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)