问题
I wrote a program as below:
#include <iostream>
using namespace std;
class A {
public:
A() {
}
A(A &a) {
id = a.id;
cout << "copy constructor" << endl;
}
A& operator=(A &other) {
id = other.id;
cout << "copy assignment" << endl;
return *this;
}
A(A &&other) {
id = other.id;
cout << "move constructor" << endl;
}
A& operator=(A &&other) {
id = other.id;
cout << "move assignment" << endl;
return *this;
}
public:
int id = 10;
};
A foo() {
A a;
return a;
}
int main()
{
A a;
A a2(a); // output: copy constructor
A a3 = a2; // output: copy constructor
a3 = a2; // output: copy assignment
A a4 = foo(); // output:
a4 = foo(); // output: move assignment
return 0;
}
I compiled it on my Mac OS. The output is:
copy constructor
copy constructor
copy assignment
move assignment
My question are:
- Why the output of
A a4 = foo();
is empty? I thought it should call the move constructor. - Why the output of
A a3 = a2;
iscopy constructor
instead ofcopy assignment
?
回答1:
Because copies and moves may be elided by the compiler if it wishes. The relevant constructor must still exist, but it is explicitly stated in the standard that they might not be invoked. (This is a rare example of a standard-defined optimisation, in particular allowing Return Value Optimisation to be standard-defined also.)
Because the use of
=
in initialisation performs construction, not assignment. It's somewhat confusing that this is the syntax.A a3(a2)
, which is [essentially] equivalent, would be clearer in this regard.
回答2:
The compiler is generating default methods for:
A (const A &);
A & operator = (const A &);
If you add the const
qualifier to your copy ctor / assign methods, you may see the results you expect.
来源:https://stackoverflow.com/questions/19613637/move-semantics-and-copy-constructor