Search code examples
c++inheritanceinterfacecompolymorphism

Interfaces and multiple inheritance


I want to design my code somehow like Microsoft's COM, meaning:

  • I have my dll with different objects implementing different interfaces,
  • I only expose the interfaces to the client (this part is not really an issue here but it's just to give more context).

Now as an example, taking this code (you can run it here https://onlinegdb.com/Z7RPQVrCZ):

class IParent
{
public:
    virtual void foo() const = 0;  
};

class IChild : public IParent
{
public:
    virtual void bar() const = 0;  
};

class Parent : public IParent
{
private:
        int a_;
        
public:
    virtual void foo() const override { /* for ex: do something with a_ */ }
};

class Child : public IChild, public Parent
{
public:
    virtual void bar() const override {}
    
    // My issue is here:
    using Parent::foo;
};

int main()
{
    Child c;
    return 0;
}

I get the compile error:

main.cpp:38:11: error: cannot declare variable ‘c’ to be of abstract type ‘Child’

Although if I replace using Parent::foo; by:

virtual void foo() const override { return Parent::foo(); }

It compiles normally. But what is the point since I don't want to override it. In some way I would even want to make Parent::foo final for example.

I imagine the issue is that Child inherits from IChild and Parent and that both inherit from IParent. But then:

  • Why the expicit using doesn't work?
  • And if it is what it is, does this mean this design just doesn't match my needs here?
  • Or do I just implement it badly?

Solution

  • So I went with @Pepijn Kramer answer. But it has some typo so I rewrite it wrt to my example case:

    class IParent
    {
    public:
        virtual void foo() const = 0;  
    };
    
    class IChild : public IParent
    {
    public:
        virtual void bar() const = 0;  
    };
    
    template<typename T>
    class Parent : public T
    {
    private:
            int a_;
            
    public:
        virtual void foo() const override { /* for ex: do something with a_ */ }
    };
    
    class Child : public Parent<IChild>
    {
    public:
        virtual void bar() const override {}
    };
    
    int main()
    {
        Child c;
        return 0;
    }