I'm creating a GUI in my C++ application and I have a class called GUIObject
which is base class for all other components, like for example Button
, CheckBox
, Window
etc.
I also have a class GUIObjectsStorage
, which consists of all GUIObject
s that are created. So far I've been working with raw pointers, so I just had this constructor for GUIObject
class:
GUIObject::GUIObject() :
{
GUIObjectsStorage::Instance().addObject(this);
}
And it was ok for my needs, because whenever I wanted to access specific object, I just took it from GUIObjectsStorage
. But now I'm trying to move into use of smart pointers, so that GUIObjectsStorage
now stores array of std::shared_ptr<GUIObject>
instead of raw pointers and I can't use my constructor as I used it before:
GUIObject::GUIObject() :
{
GUIObjectsStorage::Instance().addObject(std::shared_ptr<GUIObject>(this));
}
because for example:
// Somewhere in code
std::shared_ptr<Button> bt = std::shared_ptr<Button>(new Button());
Basically I'd now have two shared_ptr
s (one here, second in GUIObjectsStorage
, because it was added in Button
's constructor) which both have reference count = 1, yet both point to the same object in memory. Then if one of them dies, object itself is being destroyed too.
So I came up with an idea to maybe make private constructor for all classes inheriting from GUIObject
and create a static method which would create and return std::shared_ptr
and it's copy add to GUIObjectsStorage
. This way I could have shared_ptr
s with reference count = 2 which is correct:
class Button : public GUIObject
{
private:
// ...
Button();
public:
// ...
static std::shared_ptr<Button> create();
}
std::shared_ptr<Button> Button::create()
{
std::shared_ptr<Button> bt = std::shared_ptr<Button>(new Button());
GUIObjectsStorage::Instance().addObject(bt);
return bt;
}
By hiding constructor I could be sure that nobody will create an object in different way than by using create()
method.
But is this good way of designing this? If not, what could be a better solution for this problem?