Betrachten Sie die folgende Klasse:
<code class="cpp">class X { public: explicit X(char* c) { cout << "ctor" << endl; init(c); }; X(X& lv) { cout << "copy" << endl; init(lv.c_); }; X(X&& rv) { cout << "move" << endl; c_ = rv.c_; rv.c_ = nullptr; }; const char* c() { return c_; }; private: void init(char *c) { c_ = new char[strlen(c)+1]; strcpy(c_, c); }; char* c_; };</code>
Und seine Verwendung:
<code class="cpp">X x("test"); cout << x.c() << endl; X y(x); cout << y.c() << endl; X z( X("test") ); cout << z.c() << endl;</code>
Die Ausgabe ist:
ctor test copy test ctor <-- why not move? test
In VS2010 würde man bei Verwendung der Standardeinstellungen erwarten, dass das letzte Objekt (z) bewegungskonstruiert wird und nicht standardmäßig. konstruiert. Die Verwendung von X z( move(X("test")) ) führt zur erwarteten Ausgabe: ctor move test. Könnte dies ein Fall von NRVO sein?
Sollte der Verschiebungskonstruktor gemäß dem C 11-Standard aufgerufen werden? Wenn ja, warum heißt es nicht?
Das beobachtete Verhalten ist auf Kopierelision zurückzuführen. Der Compiler kann ein temporäres Objekt direkt in ein Ziel konstruieren, in das es kopiert/verschoben werden soll, wodurch die Aufrufe des Kopier-/Verschiebekonstruktors und des Destruktors entfallen.
Die Situationen, in denen Kopierelision angewendet werden kann, sind in §12.8 beschrieben. 32 des C 11-Standards:
In diesem Fall ist der Compiler in der Lage, den Kopier- oder Verschiebungsvorgang zwischen dem temporären X („test“) und dem Ziel z zu unterlassen, was zu dem beobachteten Verhalten führt.
Das obige ist der detaillierte Inhalt vonWarum wird mein C 11 Move Constructor in diesem Fall nicht aufgerufen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!