2017-08-12 49 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(); 
} 

編譯返回變量:構建和局部變量的超聲破壞和在C++

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

輸出:

A() 
~A() 

爲什麼只有一個對A()和〜A()在輸出?

爲什麼移動構造函數不被調用?

讓編譯器做了一些代碼優化?

回答

6

由於Copy Elision,移動(或複製)構造函數未被調用。編譯器直接在返回值位置構造局部變量。

這樣的優化也被稱爲RVO(返回值優化)。

編譯器有一定的條件允許這樣的優化,它們在標準中提到。但它可以更方便地引用第25條的Effective Modern C++ by Scott Meyers關於這些條件(不那麼嚴格的信息作爲標準,但也許更有效的吸收):

複述標準的墨守成規的(可以說是有毒的)的散文,[ (1)本地對象的類型與該函數返回的 相同,並且(2)如果(1)本地對象的類型與 相同,本地對象是什麼被返回。