2014-06-26 16 views
14

ich mit einer Code-Basis arbeiten, die teilweise von jemandem, der in der Liebe war mit übermäßig komplexen Lösungen für einfache Probleme (zum Beispiel Template-Klassen mit zwei Parametern, die immer nur für ein paar Typen instanziiert wurden) umgesetzt wurden. Eine Sache, die sie tat, war, Objekte in einem intelligenten Zeiger zu verursachen und das Objekt dann einen schwachen Zeiger zu sich selbst zu lassen.Shop schwache Zeiger auf Selbst

Die Klasse fährt fort, m_self zu verwenden, indem sie es sperrt und um den resultierenden gemeinsamen Zeiger herumgibt.

Für das Leben von mir, kann ich nicht ergründen, was sie zu erreichen versuchen. Gibt es ein Muster oder eine Idee, die diese Implementierung erklären? Es sieht für mich so aus, als wäre das völlig sinnlos und ich würde es gerne umgestalten.

BEARBEITEN: Ich sollte erwähnen, dass keiner der Orte, die den resultierenden Smart-Zeiger aus dem Sperren von m_self verwendet tatsächlich den Smart-Zeiger beibehalten.

+5

wussten nicht, über 'std :: shared_from_this' I –

+0

erraten C++ 98 Es ist neuere Sachen nicht verwendet –

+3

Na ok, es ist eine C++ 98-Version von' enable_shared_from_this' –

Antwort

17

Eine mögliche Verwendung dieser „Design“ könnte m_self.lock() verwenden, um freigegebene Zeiger aus dieser zu generieren.

Wenn Sie dieses schwache Zeigerelement entfernen, wäre der Verweiszähler, der von dem generierten freigegebenen Zeiger von this gehalten wird, falsch.

Es erreicht das gleiche als std::enable_shared_from_this interessanterweise cppreference.com mentions this design:

Eine übliche Implementierung für enable_shared_from_this ist eine schwache Referenz (wie std :: weak_ptr) dazu zu halten. Die Konstruktoren des std :: Shared_ptr das Vorhandensein einer enable_shared_from_this Basis erfassen und weisen das neu erstellt std :: Shared_ptr zum

schwachen Referenz intern gespeicherten

und den C++ Standard, Abschnitt § 20.8.2.4 10, erwähnt die gleiche mögliche Implementierung:

der shared_ptr Konstruktoren, die einzigartigen Zeiger erstellen kann die Anwesenheit einer enable_shared_- from_this Basis erfassen und den neu erstellt shared_ptr seine __weak_this membe zuweisen r


Mögliche Refactoring:

  • Wenn Sie mit C++ 11, können Sie das std::weak_ptr Mitglied, entfernen und erbt öffentlich von std::enable_shared_from_this<T>. Sie sollten durch den Aufruf shared_from_this() einen freigegebenen Zeiger aus diesem abrufen.

  • Wenn Sie nicht C++ 11 verwenden, aber Boost verwenden können, verwenden Sie boost::enable_shared_from_this, siehe boost documentation. Sie sollten durch den Aufruf shared_from_this() einen freigegebenen Zeiger aus diesem abrufen.

  • Wenn Sie nicht verwenden 11 C++ und Boost verwenden, können nicht Sie die vorgeschlagene Umsetzung der Norm zu Ihrer Code-Basis bringen kann, ist es kurz genug:

-Code : -

template<class T> class enable_shared_from_this { 
    private: 
    weak_ptr<T> __weak_this; 
    protected: 
    constexpr enable_shared_from_this() : __weak_this() { } 
    enable_shared_from_this(enable_shared_from_this const &) { } 
    enable_shared_from_this& operator=(enable_shared_from_this const &) { return *this; } 
    ~enable_shared_from_this() { } 
    public: 
    shared_ptr<T> shared_from_this() { return shared_ptr<T>(__weak_this); } 
    shared_ptr<T const> shared_from_this() const { return shared_ptr<T const>(__weak_this); } 
}; 

und shared_from_this() einen gemeinsamen Zeiger zu machen verwenden (11, entfernen führenden Unterstrichen, und Sie wollen es wahrscheinlich umbenennen aus § 20.8.2.4 kopiert). Wenn Sie diesen Code kopieren, beachten Sie, dass das Konstruieren gemeinsamer Zeiger auf andere Weise nicht funktioniert. Die Konstruktoren für gemeinsam genutzte Zeiger müssen geändert werden (wie durch das Standardzitat oben erläutert).

+1

Das ist keine offizielle Dokumentation –

+1

Wahr. Tatsächlich zeigt der Standard genau die gleiche mögliche Implementierung. – quantdev

+0

Yup Ich habe versucht, das zu bestätigen, aber die PDF-Suche funktionierte nicht. Ich sehe es jetzt. –