Heim > Backend-Entwicklung > C++ > Hauptteil

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

DDD
Freigeben: 2024-11-06 09:46:02
Original
245 Leute haben es durchsucht

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

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

Die erwartete Ausgabe ist:

ctor
test
copy
test
ctor move test
Nach dem Login kopieren

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!

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
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!