0

If I modify the assignment opreator so that it returns an object A instead of a reference to an object A then something funny happens.

Whenever the assignment operator is called, the copy constructor is called right afterwards. Why is this?

#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;
}

The output is as follows:

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
Jason
  • 1,297
  • 12
  • 24

1 Answers1

5

Because if you don't return a reference of the object it makes a copy. As @M.M said about the final test() call, the copy does not appears because of the copy elision What are copy elision and return value optimization?

Community
  • 1
  • 1
  • How about in the case where I call `test()` at the very bottom? No copy ctor is called, only the constructor? – Jason Nov 20 '15 at 05:18
  • 2
    @Jason [copy elision](http://stackoverflow.com/questions/12953127/what-are-copy-elision-and-return-value-optimization) occurs there. Also that would be a move rather than a copy, if you are compiling in C++11 mode. To get a better idea of what's going on, disable copy-elision and add output for your move constructor. – M.M Nov 20 '15 at 05:20