Frage

Wir haben ziemlich viel bewegt über mit boost::shared_ptr in allen unseren Code, aber noch haben wir einige Einzelfälle, wo wir std::auto_ptr verwenden, einschließlich Singleton-Klassen:

template < typename TYPE >
class SharedSingleton
{
public: 
    static TYPE& Instance()
    {
        if (_ptrInstance.get() == NULL)
            _ptrInstance.reset(new TYPE);
        return *_ptrInstance;
    }

protected: 
    SharedSingleton() {};

private:
    static std::auto_ptr < TYPE > _ptrInstance;
};

Man hat mir gesagt, dass es ein sehr guter Grund, warum dies eine shared_ptr nicht gemacht wurde, sondern für das Leben von mir, ich kann nicht verstehen, warum? Ich weiß, dass auto_ptr wird schließlich, wie im nächsten Standard abgeschrieben verkratzt, so möchte ich auf wissen, was / wie ich diese Implementierung ersetzen .

Auch gibt es andere Gründe, warum Sie anstelle eines auto_ptr ein shared_ptr betrachten würde mit? Und sehen Sie, irgendwelche Probleme zu bewegen in die Zukunft Shared_ptr?


Edit:

  1. So in der Antwort auf „kann ich ersetzen sicher auto_ptr mit shared_ptr in dem obigen Code“, lautet die Antwort ja - aber nehme ich eine kleine Performance-Einbußen
  2. .
  3. Wenn auto_ptr schließlich als abgeschrieben markiert und wir bewegen uns über std::shared_ptr, wir haben unseren Code testen müssen, um sicherzustellen, dass wir durch die unterschiedlichen Eigentums Semantik sind bleibend.
War es hilfreich?

Lösung

auto_ptr und shared_ptr lösen ganz andere Probleme. Man ersetzt nicht die anderen.

auto_ptr ist eine dünne Hülle um Zeiger RAII Semantik zu implementieren, so dass die Ressourcen immer freigegeben , auch wenn Ausnahmen gegenüber. auto_ptr führt keine Referenzzählung oder dergleichen überhaupt, ist es nicht mehrere Zeiger auf das gleiche Objekt, wenn Kopien zu erstellen. In der Tat ist es ganz anders aus. auto_ptr ist eine der wenigen Klassen, in denen der Zuweisungsoperator die Quelle modifiziert Objekt. Betrachten Sie diese schamlosen Stecker aus dem auto_ptr Wikipedia-Seite :

int *i = new int;
auto_ptr<int> x(i);
auto_ptr<int> y;

y = x;

cout << x.get() << endl; // Print NULL
cout << y.get() << endl; // Print non-NULL address i

Beachten Sie, wie die Ausführung

y = x;

ändert nicht nur y, sondern auch x.

Die boost::shared_ptr Vorlage macht es einfach, mehrere Zeiger auf das gleiche Objekt, und das Objekt wird nur dann gelöscht zu handhaben, nachdem der letzte Verweis auf sie außerhalb des Bereichs ging. Diese Funktion ist in Ihrem Szenario nicht sinnvoll, die (versucht) führen ein Singleton . In Ihrem Szenario gibt es immer entweder 0 Verweise auf 1 Bezugnahme auf das einzig Objekt der Klasse, wenn überhaupt.

Im Wesentlichen auto_ptr Objekte und shared_ptr Objekte haben ganz andere Semantik (das ist, warum Sie nicht die ehemalige in Containern verwenden können, aber so mit diesem zu tun ist in Ordnung), und ich hoffe, dass Sie gute Tests haben keine Regressionen Sie eingeführt zu fangen während Sie den Code zu portieren. : -}

Andere Tipps

Andere haben geantwortet, warum dieser Code eine auto_ptr anstelle eines shared_ptr verwendet. Um richten Sie Ihre Fragen:

Was / wie ich diese Implementierung ersetzen kann?

Verwenden Sie entweder boost::scoped_ptr oder unique_ptr (erhältlich in beiden Boost und den neuen C ++ Standard). Sowohl scoped_ptr und unique_ptr bieten strenges Eigentum (und keine Kopfreferenzzählung), andthey vermeiden die überraschende Lösch-on-Kopie Semantik von auto_ptr.

Auch gibt es andere Gründe, warum man bedenkt, würde eine auto_ptr anstelle eines shared_ptr verwenden? Und sehen Sie irgendwelche Probleme in der Zukunft shared_ptr bewegen?

Persönlich würde ich nicht eine auto_ptr verwenden. Löschen-on-Kopie ist einfach zu nicht-intuitiv. Herb Sutter scheint zustimmen. Die Umstellung auf scoped_ptr, unique_ptr oder shared_ptr sollten keine Probleme bieten. Insbesondere sollte shared_ptr einen Drop-in seinen Ersatz, wenn Sie nicht über die Referenzzählung Kopf kümmern. scoped_ptr ist ein Drop-in-Ersatz, wenn Sie nicht auto_ptr die Transfer-of-Ownership-Funktionen verwenden. Wenn Sie Transfer-of-Ownership verwenden, dann ist unique_ptr fast ein Drop-in-Ersatz, mit der Ausnahme, dass Sie stattdessen müssen explizit move nennen Eigentum zu übertragen. Siehe hier für ein Beispiel.

auto_ptr ist die einzige Art von Smart-Pointer ich verwende. Ich benutze es, weil ich nicht-Boost verwenden, und weil ich in der Regel meine Business / anwendungsorientierte Klassen bevorzugen explizit definieren Löschen Semantik und Ordnung, sondern sind abhängig von Sammlungen von oder individuelle, intelligente Zeiger.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top