Reputation: 55
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
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 individualButton
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
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