Home > Back-end >  Multiple inheritance ambiguities with minimal code clutter
Multiple inheritance ambiguities with minimal code clutter

Time:12-02

I have two interfaces: IFace2 derives from IFace

class IFace
{
public:
    virtual ~IFace() = default;

    virtual void doit() = 0;
};

class IFace2 : public IFace
{
public:
    virtual void doit2() = 0;
};

I am trying reduce code clutter that is required by the implementations. In IFace2Impl I would like to use the same implementation from IFaceImpl. Unfortunately, that forces me to resolve ambiguity and I need to override every function in IFace2Impl:

class IFaceImpl : public IFace
{
public:
    void doit() override
    {
    }
};

class IFace2Impl : public IFaceImpl, IFace2
{
public:
    using IFaceImpl::doit; // not resolving ambiguity

    void doit2() override
    {
    }
};

int main()
{
    IFace2Impl impl;
}

When I try to compile this code, the compiler gives me an error message:

<source>(36): error C2259: 'IFace2Impl': cannot instantiate abstract class
<source>(24): note: see declaration of 'IFace2Impl'
<source>(36): note: due to following members:
<source>(36): note: 'void IFace::doit(void)': is abstract
<source>(6): note: see declaration of 'IFace::doit'

https://godbolt.org/z/91M1j8bv3

For each virtual function I have to provide full definition:

class IFace2Impl : public IFaceImpl, IFace2
{
public:
    void doit() 
    { 
        IFaceImpl::doit(); 
    }

    void doit2() override
    {
    }
};

Is there a way to handle this more elegantly? When number of interface method grows, the more ambiguities I have to resolve.

CodePudding user response:

Virtual inheriance might help, so IFaceImpl would have only one IFace instead of 2:

class IFace
{
public:
    virtual ~IFace() = default;

    virtual void doit() = 0;
};

class IFace2 : public virtual IFace
{
public:
    virtual void doit2() = 0;
};

class IFaceImpl : public virtual IFace
{
public:
    void doit() override {}
};

class IFace2Impl :
    public IFaceImpl,
    public virtual IFace2 // virtual not required here, but would be with IFace3Impl...
{
public:
    void doit2() override {}
};

Demo

  • Related