Mark
Mark

Reputation: 55

To use another class inside a new class, should I inherit?

Background: I have a class Button that contains state data, textures and some member functions like draw(). Now I want to make new class Buttons that will contain a vector of Button object(s) (vector<Button> ButtonList), and member functions to maintain them and potentially trigger actions based on clicks. Button is in a separate header and cpp file. The ~Buttons takes care of deleting the individual Button objects.

Question: Do I gain any advantage in inheriting the Button class, instead of just #include Button ? Or are there pitfalls I should be aware of.

I do intend to expand on the Button class at a later date. I'm probably overthinking this a little, and I am fairly new to classes.

Example of include:

#include <vector>
#include "Button.h"

class Buttons
{
public:
    Buttons();
    ~Buttons();

    void addButton(int ID);
    void removeButton(int ID);
    void updateButtons();

private:
    std::vector<Button> buttonList;
};

Example of inherit:

#include <vector>
#include "Button.h"

class Buttons:Button
{
public:
    Buttons();
    ~Buttons();

    void addButton(int ID);
    void removeButton(int ID);
    void updateButtons();

private:
    std::vector<Button> buttonList;
};

Upvotes: 1

Views: 159

Answers (2)

Christian Hackl
Christian Hackl

Reputation: 27538

Question: Do I gain any advantage in inheriting the Button class, instead of just #include Button ?

This particular question does not make sense, because the issues are orthogonal. Both inheritance and composition with a std::vector require the full definition of Button and thus #include "button.h".

I'm probably overthinking this a little, and I am fairly new to classes.

When in doubt, favour composition over inheritance.

#include <vector>
#include "Button.h"

class Buttons
{
public:
    Buttons();
    ~Buttons();

    void addButton(int ID);
    void removeButton(int ID);
    void updateButtons();

private:
    std::vector<Button> buttonList;
};

That's a very good solution. You cannot get much cleaner C++ than that.

class Buttons:Button

This line, in contrast, does not make much sense. It uses private inheritance, which models composition, because the type is a class. I am quite sure that this is absolutely not your intention. Why would you add an extra Button if your class already contains a std::vector<Button>?

The line reads as "A Buttons object contains one Button".

Public inheritance would make even less sense, of course:

class Buttons : public Button

This would read as "A Buttons object is one Button".

private:
    std::vector<Button> buttonList;

So, combined with this line, the two inheritance versions above mean either "A Buttons object contains one Button and also some more Buttons" or "A Buttons object is one Button and also contains some Buttons".


Bottom line: Use the inheritance-less version.

There is, however, one other sentence in your question which sounds a bit alarming:

The ~Buttons takes care of deleting the individual Button objects.

Yes, but only very indirectly, because the std::vector destructor does that automatically. In fact, in the code you have shown, you do not need to declare a destructor at all. If you do any extra work in the destructor, then chances are there is something wrong.

Upvotes: 2

YSC
YSC

Reputation: 40100

You should not make Buttons inherit Button, as there would be no meaning to use an object of type Buttons where an object of type Button is expected.

Inheritance is the strongest possible relation into two (or more) classes, it should not be used for simple code refactoring, still less to define a "collection of" relation.

Upvotes: 3

Related Questions