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_ptr
ermö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.