Heim  >  Artikel  >  Backend-Entwicklung  >  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
Susan SarandonOriginal
2024-11-05 01:49:02448Durchsuche

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>

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?

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!

Stellungnahme:
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