Poroing
Poroing

Reputation: 13

How to prevent unwanted behavior when a data member of a derived class inherits from a data member of its base class?

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

Answers (1)

463035818_is_not_an_ai
463035818_is_not_an_ai

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

Related Questions