Я создаю GUI в моей C++ приложений, и у меня есть класс с именем GUIObject
, который является базовым классом для всех других компонентов, как, например, Button
CheckBox
, Window
и т.д.Статический метод для создания объекта вместо конструктора
У меня также есть класс GUIObjectsStorage
, который состоит из всех созданных GUIObject
. До сих пор я работал с сырыми указателями, так что я только что этот конструктор для класса GUIObject
:
GUIObject::GUIObject() :
{
GUIObjectsStorage::Instance().addObject(this);
}
И это было хорошо для моих потребностей, потому что всякий раз, когда я хотел получить доступ к какому-либо объекту, я просто взял его из GUIObjectsStorage
. Но теперь я пытаюсь двигаться в использовании смарт-указатели, так что GUIObjectsStorage
теперь хранит массив std::shared_ptr<GUIObject>
вместо сырых указателей, и я не могу использовать конструктор как я использовал его раньше:
GUIObject::GUIObject() :
{
GUIObjectsStorage::Instance().addObject(std::shared_ptr<GUIObject>(this));
}
, потому что, например, :
// Somewhere in code
std::shared_ptr<Button> bt = std::shared_ptr<Button>(new Button());
в основном я теперь есть два shared_ptr
с (один здесь, во-вторых, в GUIObjectsStorage
, потому что она была добавлена в Button
«конструктору), которые оба имеют счетчик ссылок = 1, но оба указывают на тот же объект в памяти. Тогда, если один из них умирает, сам объект тоже уничтожается.
Так я пришел с идеей, возможно, сделать приватный конструктор для всех классов, наследующих от GUIObject
и создать статический метод, который будет создавать и возвращать std::shared_ptr
и его копию добавить в GUIObjectsStorage
. Таким образом, я мог бы shared_ptr
со ссылкой кол = 2, который является правильным:
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;
}
Скрывая конструктор я мог быть уверен, что никто не будет создавать объект иначе, чем с помощью create()
метода.
Но это хороший способ конструировать это? Если нет, то что может быть лучшим решением для этой проблемы?
Выглядит хорошо для меня. Кроме того, я думал, что весь смысл shared_ptr заключается в том, чтобы избежать такой проблемы? – Polar
@Polar На самом деле я думаю, что вся точка 'shared_ptr' заключалась в том, чтобы избежать необходимости удаления объектов вручную, а не именно таких проблем. :-) –
Я немного смущен. Почему вы пытаетесь использовать 'shared_ptr' в первую очередь? Вы можете просто использовать указатели и уничтожить их всех в деструкторе GUIObjectsStorage. –