Multiple Inheritance, C++ and Same Method Signature in Multiple Super Classes

15,263

Solution 1

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.

Solution 2

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();
Share:
15,263

Related videos on Youtube

Sam
Author by

Sam

Updated on June 01, 2022

Comments

  • Sam
    Sam about 2 years

    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 easy. However, I am still curious on how C++ deals with that since it allows you to inherit from more than one class.

    Specifically, say there is a class called MechanicalEngineer and another called ElectricalEngineer. Both have a method called buildRobot().

    What happens if we make a third class RoboticsEngineer, that inherets from both and does not override that method, and you just call:

    (some instance of RoboticsEngineer).buildRobot()
    

    Will an exception be thrown, or the method from one of the super-classes will be used? If so, how does the compiler know which class to use?

    • toto2
      toto2 almost 13 years
      What happens in Java if a class has a method buildRobot and an interface has a method buildRobot and you define a subclass that also implements the interface?
    • toto2
      toto2 almost 13 years
      @toto Apparently it's fine as long as the return type is the same, see this thread.
  • TheOneTeam
    TheOneTeam almost 13 years
    Is reli that C++ can inherit from more than two class?
  • TheOneTeam
    TheOneTeam almost 13 years
    can be say virtual is same as the key word "implement" in java?
  • sergio
    sergio almost 13 years
    @Yochai Timmer: could you be more precise? what should be virtual in both? the inheritance or the method? Any statement I made was backed by a compiler test I did... @Kit Ho: I don't know much of Java, but since virtual inheritance makes sense for multiple inheritance, and Java has got none of this, I would doubt it...
  • Captain Obvlious
    Captain Obvlious almost 13 years
    There's really no logical reason to cast as using the scope operator is sufficient, shorter and typically more acceptable in practice.
  • Yochai Timmer
    Yochai Timmer almost 13 years
    @sergio : before you edited you said that you just need to make both methods virtual. What you have now will work. Though OP asked what happens if both base classes have an implementation of the method (The question is not about diamond inheritance)
  • sergio
    sergio almost 13 years
    @Yochai Timmer: I see your point. After reviewing my edits, let me just stress that it was possibly a matter of ambiguity in my expression, since I never spoke of making the methods virtual; rather, I was speaking of virtual inheritance. I agree with you that the part of my answer starting with "A special case" is not strictly required and is only given for completeness; the first part is the answer to the question. Thanks for your comments!
  • Pratham
    Pratham over 9 years
    In this case why will the compiler throw error/what error will be thrown? Remember interfaces in Java are like pure virtual functions. Hence C will need to implement the function and calling it will result in no ambiguity.