Sam*_*Sam 23 c++ inheritance multiple-inheritance
我没有C++经验,而且我来自Java背景.最近,我在接受采访时被问到为什么Java不允许多重继承,答案很简单.但是,我仍然很好奇C++如何处理它,因为它允许你从多个类继承.
具体来说,假设有一个叫做的类MechanicalEngineer,另一个叫做ElectricalEngineer.两者都有一个叫做的方法buildRobot().
如果我们制作第三个类会发生什么RoboticsEngineer,从两个方面都不存在并且不会覆盖该方法,并且您只需调用:
(some instance of RoboticsEngineer).buildRobot()
Run Code Online (Sandbox Code Playgroud)
是否会抛出异常,或者使用其中一个超类的方法?如果是这样,编译器如何知道要使用哪个类?
ser*_*gio 22
编译器会将此类情况(即,尝试调用(some instance of RoboticsEngineer).buildRobot())标记为错误.
发生这种情况是因为派生对象内部有两个基础对象(MechanicalEngineer实例和ElectricalEngineer实例)的副本,而单独的方法签名不足以说明要使用哪个基础对象.
如果你buildRobot在你的覆盖中RoboticsEngineer,你将能够通过为类名添加前缀来明确说明要使用的继承方法,例如:
void RoboticsEngineer::buildRobot() {
ElectricalEngineer::buildRobot()
}
Run Code Online (Sandbox Code Playgroud)
通过相同的硬币,您实际上可以"强制"编译器使用一个版本或另一个版本buildRobot,前缀为类名:
(some instance of RoboticsEngineer).ElectricalEngineer::buildRobot();
Run Code Online (Sandbox Code Playgroud)
在这种情况下,ElectricalEngineer将调用该方法的实现,没有歧义.
如果您有Engineer两个基类,MechanicalEngineer并且在两种情况下都ElectricalEngineer指定了继承,则会给出一个特例virtual.当virtual被使用时,得到的对象不包含的两个实例Engineer,但是编译器可以确保只有有它的一个.这看起来像这样:
class Engineer {
void buildRobot();
};
class MechanicalEngineer: public virtual Engineer {
};
class ElectricalEngineer: public virtual Engineer {
};
Run Code Online (Sandbox Code Playgroud)
在这种情况下,
(some instance of RoboticsEngineer).buildRobot();
Run Code Online (Sandbox Code Playgroud)
将毫不含糊地解决.如果virtual在两个派生类之一中声明并覆盖了buildRobot,情况也是如此.无论如何,如果两个派生类(ElectricalEngineer和MechanicalEngineer)都会覆盖buildRobot,则会再次出现歧义,编译器会将调用的尝试标记(some instance of RoboticsEngineer).buildRobot();为错误.
它没有处理它.这是模棱两可的.error C2385: ambiguous access of 'functionName'
编译器很聪明,知道它不应该猜测你的意思.
对于要编译的程序,您需要告诉编译器:
A.您知道这是一个有问题的问题.
B.告诉它究竟是什么意思.
为此,您需要明确告诉编译器您要求的方法:
RoboticsEngineer myRobot;
myRobot.ElectricalEngineer::buildRobot();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
12460 次 |
| 最近记录: |