Erhalten eines unique_ptr für eine Klasse, die enable_shared_from_this erbt

ormalerweise ziehe ich es vor, @ zurückzukehrunique_ptr aus Fabriken. Vor kurzem bin ich auf das Problem gestoßen, ein @ zurückzugebeunique_ptr für eine Klasse, die @ erenable_shared_from_this. Benutzer dieser Klasse rufen möglicherweise versehentlich @ aushared_from_this(), obwohl es keinem @ gehöshared_ptr, was mit einem @ resultiestd::bad_weak_ptr exception (oder undefiniertes Verhalten bis C ++ 17, das normalerweise als Ausnahme implementiert ist).

Eine einfache Version des Codes:

class Foo: public enable_shared_from_this<Foo> {
    string name;
    Foo(const string& _name) : name(_name) {}
public:
    static unique_ptr<Foo> create(const string& name) {
        return std::unique_ptr<Foo>(new Foo(name));
    }
    shared_ptr<Foo> get_shared() {return shared_from_this();}
    void doIt()const {cout << "Foo::doIt() <" << name << '>' << endl;}
    virtual ~Foo() {cout << "~Foo() <" << name << '>' << endl;}
};

int main() {
    // ok behavior
    auto pb1 = Foo::create("pb1");
    pb1->doIt();
    shared_ptr<Foo> pb2 = shared_ptr<Foo>(std::move(pb1));
    shared_ptr<Foo> pb3 = pb2->get_shared();
    pb3->doIt();

    // bad behavior
    auto pb4 = Foo::create("pb4");
    pb4->doIt();
    shared_ptr<Foo> pb5 = pb4->get_shared(); // exception
    pb5->doIt();    
}

ine mögliche Lösung besteht darin, die Werksmethode so zu ändern, dass sie @ zurückgibshared_ptr aber das ist nicht das, wonach ich suche, da in vielen Fällen tatsächlich keine Notwendigkeit zum Teilen besteht und die Dinge dadurch weniger effizient werden.

Die Frage ist, wie all das erreicht werden kann:

rlaube der Fabrik, zurückzukehrunique_ptrermöglichenunique_ptr dieser Klasse wird geteiltermöglichenshared_ptr dieser Klasse, um freigegebene Kopien zu erhalten (übershared_from_this()) Vermeiden Sie Fehler, wennunique_ptr dieser Klasse versucht, von diesem geteilt zu werden (Aufruf vonget_shared im obigen Beispiel)

Artikel 1 bis 3 werden mit dem obigen Code erfüllt, das Problem ist mit Punkt 4.

Antworten auf die Frage(12)

Ihre Antwort auf die Frage