Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ pure virtual multiple inheritance?

I need help for an implementation that uses multiple inheritance of Interfaces...

There is an existing code whith an interface which has a lot of functions. The instances are created using a factory.

class IBig
{
    // Lot of pure virtual functions
};

And his inplementation:

class CBig: public IBig
{
    // Implementation
}

I Want to split the interface in multiple smaller interfaces, but it should stay compatible to the existing code for some time.

Here is a sample of what I tried to do:

class IBaseA
{
public:
    virtual void DoA() = 0;
};

class IBaseB
{
public:
    virtual void DoB() = 0;
};

// The same interface, now based on multiple smaller interfaces
class IBig : public IBaseA, public IBaseB
{
};

class CBaseA: public IBaseA
{
public:
    virtual void DoA()
    {
        printf("DoA\n");
    }
};

class CBaseB: public IBaseB
{
public:
    virtual void DoB()
    {
        printf("DoB\n");
    }
};

// Inherit from base classes where the implementation is, and from IBig as 
// the instance of CBig is returned as IBig.
class CBig: public CBaseA, public CBaseB, public IBig
{
};

The problem here is that the class CBig cannot be instanciated. The compiler says the functions DoA and DoB are pure virtual, even if they are inplemented in CBaseA and CBaseB. What should I do if i don't want to implement again the functions, just to call the function of the base class ?

NB: I know the design is ugly, but this is only temporary until the big interface can be replaced, and.... I want to understand ! ;-)

Thanks in advance !

like image 988
Patou Avatar asked Sep 12 '14 10:09

Patou


1 Answers

Here you should use virtual inheritance. This feature assures that there is only one instance of your virtually-inherited base class when you instantiate a subclass. For your example, this would look like:

#include <cstdio>

class IBaseA
{
public:
    virtual void DoA() = 0;
};

class IBaseB
{
public:
    virtual void DoB() = 0;
};

// The same interface, now based on multiple smaller interfaces
class IBig : virtual public IBaseA,  virtual public IBaseB
//              ^                       ^
{
};

class CBaseA: virtual public IBaseA
//              ^
{
public:
    virtual void DoA()
    {
        printf("DoA\n");
    }
};

class CBaseB: virtual public IBaseB
//              ^
{
public:
    virtual void DoB()
    {
        printf("DoB\n");
    }
};

// Inherit from base classes where the implementation is, and from IBig as 
// the instance of CBig is returned as IBig.
class CBig: public CBaseA, public CBaseB, public IBig
{
};

int main()
{
    CBig cb;
}

The above changes ensure that there are not extra declarations of DoA and DoB created when you inherit from IBaseA and IBaseB multiple times.

like image 197
TartanLlama Avatar answered Oct 25 '22 10:10

TartanLlama