Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Static method to create an object instead of constructor

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 GUIObjects 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_ptrs (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_ptrs 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?

like image 765
Piotr Chojnacki Avatar asked Mar 24 '13 09:03

Piotr Chojnacki


1 Answers

The is a classic use of a Factory for making objects.

That said, you might not need this. Do you know when widgets are no longer needed? GUI managers like this often do. If so, the commenter is right: designate an owner of the object, let it delete it, and you're set.

like image 76
Mark Bernstein Avatar answered Oct 13 '22 01:10

Mark Bernstein