为什么在赋值运算符之后在此代码中调用复制构造函数?

Jas*_*son 0 c++

如果我修改赋值opreator以便它返回一个对象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;
}
Run Code Online (Sandbox Code Playgroud)

输出如下:

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
Run Code Online (Sandbox Code Playgroud)

Gab*_*ard 5

因为如果你没有返回对象的引用,它就会复制它.正如@MM所说的关于最终的test()调用,副本没有出现因为复制省略有什么是复制省略和返回值优化?

  • @Jason [copy elision](http://stackoverflow.com/questions/12953127/what-are-copy-elision-and-return-value-optimization)在那里发生.如果您在C++ 11模式下进行编译,那么这将是一个移动而不是一个副本.要更好地了解正在发生的事情,请禁用copy-elision并为移动构造函数添加输出. (2认同)