2013-03-24 10 views
7

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?

+1

Wygląda dobrze dla mnie. Ponadto myślałem, że cały problem shared_ptr polega na uniknięciu tego rodzaju problemu? – Polar

+0

@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. :-) –

+0

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. –

Odpowiedz

2

Jest to klasyczne zastosowanie fabryki do robienia przedmiotów.

To powiedziawszy, możesz tego nie potrzebować. Czy wiesz, kiedy widżety nie są już potrzebne? Menedżerowie GUI, jak to często robią. Jeśli tak, komentator ma rację: wyznacz właściciela obiektu, pozwól mu go usunąć i gotowe.

0

Można rozważyć dziedziczenie po enable_shared_from_this.

Następnie, po udostępnieniu obiektowi shared_ptr, można użyć shared_from_this(), aby uzyskać plik shared_ptr, który przechowuje obiekt.

+0

Ale problem polega na tym, że nie mam jeszcze 'shared_ptr', ponieważ chciałbym go użyć w konstruktorze, który jest jeszcze przed budowaniem obiektu. –