Search code examples
c++inheritancemultiple-inheritance

C++ How to inherit from interface with a method of other interface type?


I have this structure:

class IA
{
    virtual void foo() = 0;
};

class IB
{
    virtual IA bar() = 0;
};

So far I made the inherited versions of these two interfaces but I have difficulties with how to make concrete overriding of the IA IB::bar() method?

I mean if I have a class A inheriting from IA then how to declare the A bar() method in a class B which inherits of IB? Or perhaps I should make a third class for this matter?

Thanks! 😊

Edit: Now I have noticed that the bar() definition in IB is as follows:

virtual IA& bar() = 0;

Perhaps this will help?


Solution

  • Welcome to the wonderful world of subtle differences between Java and C++. If you come from a Java background, a value of type IA is of type IA or any subclass thereof. But in C++, a value of type IA is a concrete instance of IA, nothing more and nothing less. And your IA is abstract, hence there are no concrete instances, so as written, your IB::bar is unsatisfiable. There's no well-defined function that can ever have that type.

    Instead, when you want to do Java-style inheritance-based polymorphism (which is often not the answer in C++, but we'll assume it's the right tool for the job for the moment), you need a layer of indirection. That can be a raw pointer (IA*), a reference (IA&), or a smart pointer (unique_ptr<IA>).

    By convention, we return a smart pointer if the data is intended to be owned by the caller (i.e. the caller is responsible for freeing it when done), a reference if it's owned by someone else, and a raw pointer if we want our fellow programmers to suffer. I'll assume you intend that the caller own the IA value, so we'll use a smart pointer.

    Your interfaces can be written

    #include <memory>
    
    class IA {
      virtual void foo() = 0;
    };
    
    class IB {
        virtual std::unique_ptr<IA> bar() = 0;
    };
    

    And we can concretely implement them as follows

    class A : public IA {
      virtual void foo() {}
    };
    
    class B : public IB {
      virtual std::unique_ptr<IA> bar() {
        return std::make_unique<A>();
      }
    };