I need to implement several modules, like below,
#include <stdio.h>
class Base{
protected:
int data;
};
class ModeA : public Base{};
class ModeB : public Base{};
class ModeHybrid: public ModeA, public ModeB{
public:
void func(){printf("%d\n", this->data);}
};
int main(){
ModeHybrid mh;
mh.func();
}
where,
But, the member variable 'data' will be duplicated, as 'ModeHybrid' inherit from both 'ModeA' and 'ModeB'.
Is there any way to avoid this?
There are at least three ways to fix this.
The first is virtual
inheritance, which has overhead. In it, you only have one Base
.
class ModeA : public virtual Base{};
class ModeB : public virtual Base{};
it does mean that the most-derived class you instantiate must construct Base
.
Another approach is template based, where you pass in the class you want the parent to derive from.
class Base{
protected:
int data;
};
template<class B=Base>
class ModeA : public B{};
template<class B=Base>
class ModeB : public B{};
class ModeHybrid:
public ModeA<ModeB<Base>>
{
public:
void func(){printf("%d\n", this->data);}
};
Another approach is to stuff the data somewhere else, and make Base
an abstract interface with a getData()
method.
class Base{
protected:
int readData() const = 0;
int& writeData() = 0;
};
class ModeA : public Base{};
class ModeB : public Base{};
class ModeHybrid:
public ModeA, public ModeB
{
public:
void func(){printf("%d\n", this->readData());}
};
template<class X>
struct ImplementBase:X {
int data;
int readData() const final { return data; }
int& writeData() final { return data; }
};
ImplementBase<ModeHybrid> hybrid;
This version has two Base
classes in its hierarchy, but we don't really care. The data exists in ImplementBase
.