Heim  >  Artikel  >  Backend-Entwicklung  >  Warum wird der C 11 Move-Konstruktor nicht aufgerufen, wenn ein Objekt aus einem temporären Objekt erstellt wird?

Warum wird der C 11 Move-Konstruktor nicht aufgerufen, wenn ein Objekt aus einem temporären Objekt erstellt wird?

Patricia Arquette
Patricia ArquetteOriginal
2024-11-04 19:17:02216Durchsuche

Why isn't the C  11 Move Constructor Called When Creating an Object from a Temporary Object?

C 11-Verschiebungskonstruktor nicht aufgerufen, Standardkonstruktor bevorzugt

In bestimmten Szenarien kann der C 11-Verschiebungskonstruktor nicht aufgerufen werden, was den Vorteil hat Stattdessen wird der Standardkonstruktor verwendet. Um zu verstehen, warum, schauen wir uns ein Beispiel an.

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 dieser Klasse können wir Objekte wie folgt erstellen:

<code class="cpp">int main() {
    X x("test");
    cout << x.c() << endl;
    X y(x);
    cout << y.c() << endl;
    X z( X("test") );
    cout << z.c() << endl;

    return 0;
}</code>

The Die erwartete Ausgabe wäre:

ctor
test
copy
test
ctor  <-- Why not move?
test

Wir beobachten jedoch, dass der Verschiebungskonstruktor in der letzten Zeile nicht aufgerufen wird. Stattdessen wird der Standardkonstruktor verwendet. Um dies zu erklären, müssen wir Kopierelision verstehen.

Kopierelision ist eine Optimierungstechnik, die der C 11-Standard unter bestimmten Bedingungen zulässt. Es ermöglicht dem Compiler, ein temporäres Objekt direkt in das Zielobjekt zu konstruieren, wodurch der Aufwand für das Kopieren/Verschieben von Konstruktoren und Destruktoren vermieden wird.

In diesem Beispiel wird das aus dem temporären „Test“ erstellte X-Objekt in z eliminiert. Dies bedeutet, dass kein Kopier-/Verschiebekonstruktor aufgerufen wird und stattdessen das Objekt direkt in z konstruiert wird.

Der Compiler kann eine Kopierelision durchführen, wenn alle diese Bedingungen erfüllt sind:

  • Das Objekt ist ein temporäres Objekt, das nicht an eine Referenz gebunden wurde.
  • Das Objekt wird in ein Objekt desselben cv-unqualifizierten Typs kopiert/verschoben.

In unserem In diesem Fall sind diese Bedingungen erfüllt und es kommt zu einer Kopierelision, die dazu führt, dass der Standardkonstruktor anstelle des Verschiebungskonstruktors verwendet wird. Um den Move-Konstruktor explizit aufzurufen, können Sie std::move verwenden, wie in:

<code class="cpp">X z( std::move(X("test")) );</code>
gezeigt

Das obige ist der detaillierte Inhalt vonWarum wird der C 11 Move-Konstruktor nicht aufgerufen, wenn ein Objekt aus einem temporären Objekt erstellt wird?. 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