2

I have this sample code:

#include <iostream>

struct Interface1
{
    virtual int getID()=0;
};

struct Interface2 : Interface1
{
    virtual int add(int a,int b)=0;
};

struct Base1 : Interface1
{
     virtual int getID() override { return 1; }
};

struct myClass: Interface2, Base1
{
    virtual int add(int a,int b) override { return a+b; }
};

int main()
{
    myClass c;     
    std::cout << c.add(0, 1) << "\n";
}

the idea is that myClass is based on Interface2, but uses Base1 as an implementation of Interface1. when I compile this code, I am getting this error:

getId is ambiguous. 

How can I fix it?

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
mans
  • 17,104
  • 45
  • 172
  • 321
  • possible duplicate of https://stackoverflow.com/questions/254673/multiple-inheritance-from-two-derived-classes – Mike van Dyke Dec 12 '17 at 12:25
  • @mans: I've simplified your snipet (replaced class by struct, get rid of all that public noise). I hope this is an improvement, rollback it if you disagree. – YSC Dec 12 '17 at 12:31
  • @mans, I've fluffed it up further with an `int main()`. – Bathsheba Dec 12 '17 at 12:34

1 Answers1

3

The thing is that myClass inherits two times from Interface1 (once from Interface1, once from Base1), thus inheriting two pure virtual functions (myClass::getID and Base1::getID). Since only one of them is implemented, if you try and create a myClass object, the compiler complains about myClass being an abstract type. And it is right.

The solution (other than using simpler inheritance) would be to make your classes inherit from Interface1 virtually:

#include <iostream>

struct Interface1
{
    virtual int getID()=0;
};

struct Interface2 : virtual Interface1
{
    virtual int add(int a,int b)=0;
};

struct Base1 : virtual Interface1
{
     virtual int getID() override { return 1; }
};

struct myClass: Interface2, Base1
{
    virtual int add(int a,int b) override { return a+b; }
};

int main()
{
    myClass c;
    std::cout << c.getID() << "\n"; // prints 1
}
Bathsheba
  • 231,907
  • 34
  • 361
  • 483
YSC
  • 38,212
  • 9
  • 96
  • 149
  • this works, but it give me a warning that getID is inherited by dominance. I checked for this message and it is not important and can be ignored. Is there any way to make sure that this warning doesn't show during compilation? – mans Dec 12 '17 at 13:06
  • @mans silence it with a pragma, but I'd rather let it be: this kind of inheritance pattern is fairly weak and fragile; it might prevent someone to break it someday and get the hell of an UB. – YSC Dec 12 '17 at 13:15