2015-11-20 32 views
0

如果我修改賦值處理器,使其返回對象A而不是對象A的引用,那麼會發生一些有趣的事情。爲什麼在賦值運算符之後在此代碼中調用了複製構造函數?

無論何時調用賦值運算符,複製構造函數都會在之後調用。爲什麼是這樣?

#include <iostream> 
using namespace std; 

class A { 
private: 
    static int id; 
    int token; 
public: 
    A() { token = id++; cout << token << " ctor called\n";} 
    A(const A& a) {token = id++; cout << token << " copy ctor called\n"; } 
    A /*&*/operator=(const A &rhs) { cout << token << " assignment operator called\n"; return *this; } 
}; 

int A::id = 0; 

A test() { 
    return A(); 
} 

int main() { 
    A a; 
    cout << "STARTING\n"; 
    A b = a; 
    cout << "TEST\n"; 
    b = a; 
    cout << "START c"; 
    A *c = new A(a); 
    cout << "END\n"; 
    b = a; 
    cout << "ALMOST ENDING\n"; 
    A d(a); 
    cout << "FINAL\n"; 
    A e = A(); 
    cout << "test()"; 
    test(); 

    delete c; 
    return 0; 
} 

輸出如下:

0 ctor called 
STARTING 
1 copy ctor called 
TEST 
1 assignment operator called 
2 copy ctor called 
START c3 copy ctor called 
END 
1 assignment operator called 
4 copy ctor called 
ALMOST ENDING 
5 copy ctor called 
FINAL 
6 ctor called 
test()7 ctor called 
+3

更改'/ *&* /'到'&',此副本將奇蹟般地消失... –

回答

5

因爲如果不返回對象的引用它使一個副本。 正如@MM所說的最終測試()調用,副本不會出現,因爲複製elision What are copy elision and return value optimization?

+0

如何關於在最底層調用'test()'的情況?沒有複製ctor被調用,只有構造函數? – Jason

+2

@Jason [複製elision](http://stackoverflow.com/questions/12953127/what-are-copy-elision-and-return-value-optimization)發生在那裏。如果您使用C++ 11模式進行編譯,那也是一個舉動而不是副本。要更好地瞭解發生了什麼,請禁用copy-elision併爲移動構造函數添加輸出。 –

相關問題