对于菱形继承问题 C++与Java不同的解决方案

对于菱形继承问题 C++与Java不同的解决方案

菱形继承定义

菱形继承问题是由于编程语言允许多继承所导致的. 最简单的例子如下:
继承关系形成了封闭的菱形

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; // 主修课程
};

D类在进行实例化时,类实例化顺序如下(按分支进行):
A(从 B 路径的基类 A 实例化)=> B => A(从 C 路径的基类 A 再次实例化)=> C => D,

D类在进行实例化时A类被实例化了两次,由此可能引出的二义性问题例子如下:
D d;
d._name = "李华";   //报错,C,D是通过普通(非虚拟)的方式继承A,那么D在内存中会包含两个独立的A类string _name成员变量
//这会导致菱形继承问题,即孙类中有两份祖父类的成员变量副本,变量名称相同,但存储位置不同。要访问其中某个成员变量时,需要明确指出它来自哪个父类。
d.B::_name = "李华";  //正确
d.C::_name = "李华";  //正确

原因:
在单继承情况下,编译器可以通过符号命名将成员变量在内存中唯一标识,以确保它们在使用时不会与其他成员产生冲突。在多继承情况下,如果两个基类中有相同名字的成员变量,编译器会遇到命名冲突,因此需要使用作用域解析来明确成员的来源.
如下图所示, d对象内存空间拥有2个A对象的实例空间,则两个A对象的相同名称成员变量会产生冲突。注意:区别于成员变量,成员函数为类所有. 实例化时对象的内存空间只为非静态成员变量分配内存空间. 而成员函数存放于代码段被所有类对象共享.
在这里插入图片描述

菱形继承问题解决(C++):

虚拟继承:虚拟继承确保无论通过哪个路径继承,只有一个A的实例存在于D中.

菱形继承问题解决(Java):

只允许单继承机制,并提出接口。一个类允许实现多个接口,接口作为功能接口不允许定义成员变量(避免二义性),且接口中声明的成员函数其派生类必须进行重写。

参考:
https://blog.youkuaiyun.com/Jdxxwu/article/details/143181746

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值