2013-03-24 3 views
7

Я создаю GUI в моей C++ приложений, и у меня есть класс с именем GUIObject, который является базовым классом для всех других компонентов, как, например, ButtonCheckBox, 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() метода.

Но это хороший способ конструировать это? Если нет, то что может быть лучшим решением для этой проблемы?

+1

Выглядит хорошо для меня. Кроме того, я думал, что весь смысл shared_ptr заключается в том, чтобы избежать такой проблемы? – Polar

+0

@Polar На самом деле я думаю, что вся точка 'shared_ptr' заключалась в том, чтобы избежать необходимости удаления объектов вручную, а не именно таких проблем. :-) –

+0

Я немного смущен. Почему вы пытаетесь использовать 'shared_ptr' в первую очередь? Вы можете просто использовать указатели и уничтожить их всех в деструкторе GUIObjectsStorage. –

ответ

2

Это классическое использование фабрики для изготовления предметов.

Это значит, что вам это может не понадобиться. Знаете ли вы, когда виджеты больше не нужны? Такие менеджеры GUI часто делают. Если это так, комментатор прав: назначьте владельца объекта, пусть он его удалит, и вы настроены.

0

Вы можете наследовать с enable_shared_from_this.

После того, как у вас есть shared_ptr для объекта, вы можете использовать shared_from_this(), чтобы получить shared_ptr, который содержит объект.

+0

Но проблема в том, что у меня еще нет 'shared_ptr', потому что я бы хотел использовать его в конструкторе, который еще до построения объекта. –

Смежные вопросы