2015-11-20 49 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并为移动构造函数添加输出。 –

相关问题