2013-03-24 11 views
7

Ich erstelle eine GUI in meiner C++ Anwendung zu erstellen, und ich habe eine Klasse namens GUIObject, die für alle andere Komponenten der Basisklasse ist, wie zum Beispiel Button, CheckBox, Window usw.Statische Methode ein Objekt statt Konstruktor

Ich habe auch eine Klasse GUIObjectsStorage, die aus allen GUIObject s besteht, die erstellt werden. Bisher habe ich bisher mit rohen Zeigern arbeiten, so hatte ich nur diesen Konstruktor für GUIObject Klasse:

GUIObject::GUIObject() : 
{ 
    GUIObjectsStorage::Instance().addObject(this); 
} 

Und es war in Ordnung für meine Bedürfnisse, weil, wenn ich bestimmte Objekt zugreifen wollte, habe ich es nur entnahm GUIObjectsStorage. Aber jetzt versuche ich, in Anwendung von Smart-Pointer zu bewegen, so dass GUIObjectsStorage jetzt Array von std::shared_ptr<GUIObject> anstelle von rohen Zeigern speichert, und ich kann meinen Konstruktor nicht benutzen, wie ich es vorher verwendet:

GUIObject::GUIObject() : 
{ 
    GUIObjectsStorage::Instance().addObject(std::shared_ptr<GUIObject>(this)); 
} 

weil zum Beispiel :

// Somewhere in code 
std::shared_ptr<Button> bt = std::shared_ptr<Button>(new Button()); 

Grundsätzlich würde ich habe jetzt zwei shared_ptr s (eine hier, die zweite in GUIObjectsStorage, weil es in Button ‚s Konstruktor hinzugefügt wurde), die beide Referenzzahl = 1, doch beide auf das gleiche Objekt haben in Erinnerung. Wenn einer von ihnen stirbt, wird auch das Objekt selbst zerstört.

So kam ich mit einer Idee bis zu vielleicht privaten Konstruktor für alle Klassen von GUIObject erben zu machen und eine statische Methode zu schaffen, und zurückkehren würde erstellen std::shared_ptr und es ist zu GUIObjectsStorage Kopie hinzufügen. Auf diese Weise konnte ich shared_ptr s mit Referenzzähler haben = 2, die korrekt ist:

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; 
} 

Durch Konstruktor versteckt ich sicher sein konnte, dass niemand ein Objekt auf unterschiedliche Weise erstellen als durch create() Methode.

Aber ist das eine gute Möglichkeit, dies zu entwerfen? Wenn nicht, was könnte eine bessere Lösung für dieses Problem sein?

+1

Sieht gut aus für mich. Außerdem dachte ich, der ganze Punkt von shared_ptr wäre, diese Art von Problem zu vermeiden? manuell zu löschen, nicht genau diese Art von Fragen – Polar

+0

@Polar Eigentlich denke ich, der ganze Punkt von 'shared_ptr' Notwendigkeit Objekte zu vermeiden war. :-) –

+0

Ich bin etwas verwirrt. Warum versuchst du 'shared_ptr's an erster Stelle zu verwenden? Sie könnten einfach direkt Zeiger verwenden und sie alle in 'GUIObjectsStorage's Destruktor zerstören. –

Antwort

2

Das ist eine klassische Verwendung einer Fabrik zur Herstellung von Objekten.

Das sagte, Sie könnten dies nicht benötigen. Weißt du, wann Widgets nicht mehr benötigt werden? GUI-Manager wie diese tun es oft. Wenn dem so ist, hat der Kommentator Recht: Einen Eigentümer des Objekts bestimmen, es löschen lassen und schon ist es soweit.

0

Sie könnten von enable_shared_from_this erben.

Nachdem Sie ein shared_ptr zu dem Objekt haben, können Sie shared_from_this() verwenden, um das shared_ptr abzurufen, das das Objekt enthält.

+0

Aber das Problem ist, dass ich 'shared_ptr' noch nicht habe, weil ich es im Konstruktor verwenden möchte, der noch vor der Konstruktion des Objekts ist. –

Verwandte Themen