Home > front end >  Extend an interface whilst not having to reimplement its functions
Extend an interface whilst not having to reimplement its functions

Time:03-14

I'm struggling with interface inheritance a little. What I'm trying to achieve is that I would like to extend an interface, whilst not having to reimplement all of its functions by reusing the function implementations from an implementation of the parent interface. Is this even possible?

So suppose I have two interfaces, from which the second (IB) inherits from the first (IA)

class IA
{
    public:
        virtual void funcA() const = 0;
};

class IB : public IA
{
    public:
        virtual void funcB() const = 0;
};

class AImpl : public IA
{
    public:
        virtual void funcA() const override {std::cout << "funcA from AImpl" << std::endl;};
};

class BImpl: public IB
{
    public:
        virtual void funcA() const override {std::cout << "funcA from BImpl" << std::endl;};
        virtual void funcB() const override {std::cout << "funcB" << std::endl;};
};

int main()
{
    BImpl b = BImpl();
    b.funcA();
    b.funcB();
    return 0;
}

which obviously gives me the expected output

funcA from BImpl
funcB

However, what I'd rather like to have is that BImpl uses the implementation of funcA from AImpl (as if it would only inherit from AImpl):

funcA from AImpl
funcB

I tried to have BImpl inherit from IB and AImpl, but that dosn't work (BImpl becomes abstract if I don't implement funcA again). The reason why I don't have BImpl inherit only from AImpl and add funcB is that I'd like to have a separate interface (IB) to code against for objects of type BImpl which, at the same time, allows me to call funcA without casting the objects to type IA (hence the interface inheritance).

// EDIT START (10th March)

That is, I'd like my business logic to look like this

int main()
{
    IB* b = new BImpl();
    b->funcA();
    b->funcB();
    return 0;
}

which requires IB to inherit from IA.

// EDIT END

Any ideas? Ideally, I would not even have to make funcA in BImpl a wrapper for funcA in AImpl (as said, as if I was inheriting from AImpl alone)

CodePudding user response:

Use virtual inheritance to take advantage of function dominance rules.

I'm rusty on how exactly dominance works, but it happens to do the right thing in this case.

#include <iostream>

class IA
{
  public:
    virtual void funcA() const = 0;
};

class IB : public virtual IA
{
  public:
    virtual void funcB() const = 0;
};

class AImpl : public virtual IA
{
  public:
    void funcA() const override {std::cout << "funcA" << std::endl;};
};

class BImpl : public AImpl, public IB
{
  public:
    void funcB() const override {std::cout << "funcB" << std::endl;};
};

int main()
{
    BImpl b;
    b.funcA(); // funcA
    b.funcB(); // funcB
    return 0;
}
  • Related