Tworzę GUI w mojej aplikacji C++ i mam klasy o nazwie GUIObject
która jest klasą bazową dla wszystkich innych komponentów, takich jak na przykład Button
, CheckBox
, Window
itpmetoda statyczna, aby utworzyć obiekt zamiast konstruktora
Mam również klasę GUIObjectsStorage
, która składa się ze wszystkich utworzonych GUIObject
s. Do tej pory pracuję z surowych wskaźników, więc miałem tylko ten konstruktor GUIObject
zajęć:
GUIObject::GUIObject() :
{
GUIObjectsStorage::Instance().addObject(this);
}
i było ok dla moich potrzeb, ponieważ gdy chciałem, aby uzyskać dostęp konkretnego obiektu, po prostu wziął ją od GUIObjectsStorage
. Ale teraz staram się przenieść do wykorzystania inteligentnych wskaźników, tak aby GUIObjectsStorage
teraz przechowuje tablicę std::shared_ptr<GUIObject>
zamiast surowych wskaźników i nie mogę używać mojego konstruktora jak użyłem go przed:
GUIObject::GUIObject() :
{
GUIObjectsStorage::Instance().addObject(std::shared_ptr<GUIObject>(this));
}
bo na przykład :
// Somewhere in code
std::shared_ptr<Button> bt = std::shared_ptr<Button>(new Button());
zasadzie, że teraz dwa shared_ptr
s (jeden o drugi w GUIObjectsStorage
, ponieważ dodano Button
jest konstruktor), które mają zarówno licznika odniesienia = 1, ale obie wskazują na ten sam przedmiot w pamięci. Wtedy, gdy jeden z nich umiera, sam przedmiot ulega zniszczeniu.
Więc wpadłem na pomysł, żeby może zrobić prywatny konstruktor dla wszystkich klas dziedziczących z GUIObject
i utworzyć statyczną metodę, która będzie tworzyć i powrotu std::shared_ptr
i to kopia dodać do GUIObjectsStorage
. W ten sposób mogę mieć shared_ptr
sz liczby odniesienia = 2, co jest poprawne:
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;
}
Ukrywając konstruktora mogę mieć pewność, że nikt nie będzie utworzyć obiekt w inny sposób niż za pomocą create()
metody.
Ale czy to dobry sposób na zaprojektowanie tego? Jeśli nie, jakie może być lepsze rozwiązanie tego problemu?
Wygląda dobrze dla mnie. Ponadto myślałem, że cały problem shared_ptr polega na uniknięciu tego rodzaju problemu? – Polar
@Polar Właściwie uważam, że cały punkt 'shared_ptr' polegał na tym, aby uniknąć ręcznego usuwania obiektów, a nie takich właśnie problemów. :-) –
Jestem lekko zdezorientowany. Dlaczego w pierwszej kolejności używasz 'shared_ptr's? Możesz bezpośrednio użyć wskaźników i zniszczyć je wszystkie w destruktorze GUIObjectsStorage. –