Heim > Backend-Entwicklung > C++ > Warum wird mein C 11 Move Constructor in diesem Fall nicht aufgerufen?

Warum wird mein C 11 Move Constructor in diesem Fall nicht aufgerufen?

Susan Sarandon
Freigeben: 2024-11-05 01:49:02
Original
534 Leute haben es durchsucht

Why Doesn't My C  11 Move Constructor Get Called in This Case?

C 11 Move Constructor Not Called, Default Constructor Preferred

Problem

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>
Nach dem Login kopieren

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>
Nach dem Login kopieren

Die Ausgabe ist:

ctor
test
copy
test
ctor   <-- why not move?
test
Nach dem Login kopieren

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?

Frage

Sollte der Verschiebungskonstruktor gemäß dem C 11-Standard aufgerufen werden? Wenn ja, warum heißt es nicht?

Antwort

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 einer Funktion mit einem Klassenrückgabetyp, wenn der Rückgabeausdruck ein nichtflüchtiges automatisches Objekt mit demselben Typ wie der Rückgabetyp ist.
  • In einem Throw-Ausdruck, wenn der Operand ein nichtflüchtiges automatisches Objekt mit einem Gültigkeitsbereich ist, der nicht über den umschließenden Try-Block hinausgeht.
  • Wenn ein Klassenobjekt kopiert wird, das nicht an eine Referenz gebunden ist /in ein Klassenobjekt mit demselben Typ verschoben.
  • Wenn der Ausnahmehandler ein Objekt desselben Typs wie das Ausnahmeobjekt deklariert, indem er die Ausnahmedeklaration als Alias ​​behandelt.

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!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage