I have no experience in C++, and I come from a Java background. Lately, I was asked in an interview on why Java would not allow multiple inheritence and the answer was pretty ea
struct MecEngineer {
void buildRobot() { /* .... */ }
};
struct EleEngineer {
void buildRobot() { /* .... */ }
};
struct RoboticsEngineer : MecEngineer, EleEngineer {
};
Now when you do,
robEngObject -> buildRobot() ;
Such a call cannot be resolved and is ambiguous because both the sub-objects has a member function with same signature and compiler doesn't know which one to call. In such a situation, you need to explicitly mention it using ::
operator or by using static_cast
.
static_cast<MecEngineer*> (robEngObject) -> buildRobot() ;
There is nothing about multiple class inheritance that allows this. Java produces the same problem with interfaces.
public interface A {
public void doStuff();
}
public interface B {
public void doStuff();
}
public class C implements A, B {}
The simple answer is that the compiler throws an error on it.
The compiler will flag this kind of situation (i.e., attempting to call (some instance of RoboticsEngineer).buildRobot()
) as an error.
This happens because the derived object has got a copy of both base objects (a MechanicalEngineer
instance and an ElectricalEngineer
instance) inside of itself and the method signature alone is not enough to tell which one to use.
If you override buildRobot
in your RoboticsEngineer
, you will be able to say explicitly which inherited method to use by prefixing the class name, e.g.:
void RoboticsEngineer::buildRobot() {
ElectricalEngineer::buildRobot()
}
By the same coin, you can actually "force" the compiler to use one version or another of buildRobot
by prefixing it with the class name:
(some instance of RoboticsEngineer).ElectricalEngineer::buildRobot();
in this case the ElectricalEngineer
implementation of the method will be called, no ambiguity.
A special case is given when you have an Engineer
base class to both MechanicalEngineer
and ElectricalEngineer
and you specify the inheritance to be virtual
in both cases. When virtual
is used, the derived object does not contain two instances of Engineer
, but the compiler makes sure that there is only one of it. This would look like this:
class Engineer {
void buildRobot();
};
class MechanicalEngineer: public virtual Engineer {
};
class ElectricalEngineer: public virtual Engineer {
};
In this case,
(some instance of RoboticsEngineer).buildRobot();
will be resolved without ambiguities. The same is true if buildRobot is declared virtual
and overridden in one of the two derived classes. Anyway, if both derived classes (ElectricalEngineer and MechanicalEngineer) overrides buildRobot
, then ambiguity arises once again and the compiler will flag the attempt at calling (some instance of RoboticsEngineer).buildRobot();
as an error.
The compiler will complain about this kind of situtation.
In such a case c++ suggest to create an Interface with a "pure virtual" method buildRobot() function. MechanicalEngineer and EletricalEnginner will inherit the Interface and override the buildRoboot() function.
When you create RoboticsEnginner object and call the buildRobot() function, the interface's function will be called.
It doesn't handle it. It's ambiguous. error C2385: ambiguous access of 'functionName'
The compiler is smart enough to know that it shouldn't guess your meaning.
For the program to compile, you need to tell the compiler that:
A. You know it's a problematic issue.
B. Tell it what exactly you mean.
To do this, you need to explicitly tell the compiler which method you're asking for:
RoboticsEngineer myRobot;
myRobot.ElectricalEngineer::buildRobot();