Reputation: 13
I have an issue with the following class structure,
class Base { int a; };
class Derived : public Base { int b; };
class OtherBase { Base c; };
class OtherDerived : public OtherBase { Derived d; };
The issue is that OtherDerived
stores two instances of Base
, one through the
inheritance to OtherBase
and one from the inheritance to Base
of the data
member d
. I would like OtherDerived
to store only one instance of Base
.
What are the possible to achieve that while minimizing code duplication ?
One possible solution would be to use multiple inheritance:
class Base { int a; };
class Derived : public virtual Base { int b; };
class OtherBase : public virtual Base {};
class OtherDerived : public OtherBase, public Derived {};
However, here, it might not make sense for OtherBase
to inherit from Base
,
we might not want to present the Base
interface to the user through
OtherBase
.
A way to solve the issue would be to use private inheritance:
class Base { int a; };
class Derived : public virtual Base { int b; };
class OtherBase : private virtual Base {};
class OtherDerived : public OtherBase, private Derived {};
In this case, I'm wondering if it is good practice to use inheritance as a
substitute for a data member. I have been taught that inheritance of Derived
on Base
should be present when “a Derived
is also a Base
”. In the
suggested data structure, OtherBase
might not be a Base
. Is my undestanding
of good practices concerning inheritance wrong or outdated ?
PS: I'm open to suggestion for an easier to read question's title.
Upvotes: 1
Views: 66
Reputation: 122476
If OtherDerived
needs a Derived
member, but not its Base
part then there is something wrong with your design. It means that Derived
is doing more than it should. Either it needs to have Base
as base to be fully functional or not. It cannot be both. Use this instead:
class Base { int a; };
class Foo { int b;}
class OtherBase { Base c; };
class OtherDerived : public OtherBase { Foo d; };
And If you actually do need the original Derived
elsewhere, it can be
class Derived : public Base, Foo {};
Upvotes: 1