多个超类中的多重继承,C++和相同方法签名

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();为错误.


Yoc*_*mer 5

它没有处理它.这是模棱两可的.error C2385: ambiguous access of 'functionName'

编译器很聪明,知道它不应该猜测你的意思.
对于要编译的程序,您需要告诉编译器:
A.您知道这是一个有问题的问题.
B.告诉它究竟是什么意思.

为此,您需要明确告诉编译器您要求的方法:

RoboticsEngineer myRobot;
myRobot.ElectricalEngineer::buildRobot();
Run Code Online (Sandbox Code Playgroud)