Heim  >  Artikel  >  Backend-Entwicklung  >  Warum wird der Move-Konstruktor in C 11 nicht aufgerufen, wenn die Kopierelision aktiviert ist?

Warum wird der Move-Konstruktor in C 11 nicht aufgerufen, wenn die Kopierelision aktiviert ist?

DDD
DDDOriginal
2024-11-06 09:46:02246Durchsuche

Why Is the Move Constructor Not Called in C  11 When Copy Elision Is Enabled?

C 11 Move-Konstruktor nicht aufgerufen, Standardkonstruktor bevorzugt

Bei der Arbeit mit Klassen in C wird erwartet, dass Move-Konstruktoren verwendet werden effizienter Ressourcentransfer. In einigen Fällen kann jedoch unerwartet stattdessen der Standardkonstruktor ausgewählt werden.

Problemstellung

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>

Mit die Beispielverwendung:

<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 erwartete Ausgabe ist:

ctor
test
copy
test
ctor move test

Die letzte Zeile gibt jedoch unerwartet „ctor“ anstelle von „move“ aus.

Erklärung

Gemäß dem C 11-Standard sollten Bewegungskonstruktoren in bestimmten Situationen aufgerufen werden. In diesem Fall sollte beim Konstruieren von z mit X("test") eine Verschiebung erfolgen. Stattdessen wird jedoch der Standardkonstruktor aufgerufen.

Dieses Verhalten ist auf die Kopierelision zurückzuführen, eine Optimierungstechnik, die es dem Compiler ermöglicht, ein temporäres Objekt direkt in ein Ziel zu konstruieren, ohne einen Kopier- oder Verschiebevorgang auszuführen. Diese Optimierung gilt in Fällen, in denen der Compiler feststellt, dass der Kopier-/Verschiebevorgang unnötig ist und eliminiert werden kann.

Im gegebenen Szenario betrachtet der Compiler das temporäre X („test“) als Kandidaten für die Kopierelision. da es automatisch innerhalb desselben Ausdrucks erstellt und zerstört wird. Folglich wird die Verschiebungsoperation weggelassen und z direkt unter Verwendung der temporären Daten erstellt, was zum Aufruf des Standardkonstruktors führt.

Schlussfolgerung

Kopieren kann zu unerwarteten Ereignissen führen Verhalten bei der Arbeit mit Verschiebungskonstruktoren, da es verhindern kann, dass der Verschiebungskonstruktor in Situationen aufgerufen wird, in denen dies erwartet wird. Compiler können die Kopierelision basierend auf ihren Optimierungsheuristiken anwenden, die je nach Compiler und Optimierungseinstellungen variieren können. Es ist wichtig, sich der Kopierelision und ihrer möglichen Auswirkungen auf das Programmverhalten bewusst zu sein.

Das obige ist der detaillierte Inhalt vonWarum wird der Move-Konstruktor in C 11 nicht aufgerufen, wenn die Kopierelision aktiviert ist?. 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