2017-08-12 2 views
2
#include <iostream> 
using namespace std; 

class A { 
public: 
    A() { 
     cout << "A()" << endl; 
    } 
    A(const A& a) { 
     cout << "A(const A& a)" << endl; 
    } 
    A(A&& a) { 
     cout << "A(A&& a)" << endl; 
    } 
    A& operator=(const A& a) { 
     cout << "operator=(const A& a)" << endl; 
     return *this; 
    } 
    A& operator=(A&& a) { 
     cout << "operator=(A&& a)" << endl; 
     return *this; 
    } 
    ~A() { 
     cout << "~A()" << endl; 
    }; 
}; 

A foo() { 
    A a; 
    return a; 
} 

int main() { 
    A a = foo(); 
} 

Compile:Constructing und Destructing von lokalen Variablen und Rück Variable in C++

clang++ test.cpp -o test -std=c++11 

Ausgang:

A() 
~A() 

Warum gibt es nur ein Paar von A() und ~ A() in der Ausgabe?

Warum wird der Move-Konstruktor nicht aufgerufen?

Haben die Compiler eine Code-Optimierung durchgeführt?

Antwort

6

Move (oder Copy) -Konstruktor wird wegen Copy Elision nicht aufgerufen. Compiler konstruierte lokale Variable in der Rückgabewert direkt platzieren.

Solche Optimierungen werden auch als RVO (Return Value Optimization) bezeichnet.

Es gibt bestimmte Bedingungen für den Compiler, solche Optimierungen zuzulassen, und sie werden in Standard erwähnt. Aber es bequemer kann Punkt 25 von Effective Modern C++ by Scott Meyers in Bezug auf diesen Bedingungen zu zitieren (nicht so strenge Informationen wie in der Norm, aber vielleicht effizienter zu absorbieren):

In Anlehnung an die legalistische (wohl giftig) Prosa des Standard [ ...] Compiler können das Kopieren (oder Verschieben) eines lokalen Objekts in einer Funktion unterstützen, die als Wert zurückgibt, wenn (1) der Typ des lokalen Objekts der gleiche ist wie der von der Funktion zurückgegebene und (2) Das lokale Objekt wird zurückgegeben.

Verwandte Themen