Reputation: 31
When i write "f5() = X(33);"
(when move constructor in comment line) the compiler does not throw errors.
But when I add a Move Constructor compiler says:
" 'X &X::operator =(const X &)': attempting to reference a deleted function "
is move constructor delete assignment operator ??
#include <iostream>
class X {
int* p;
public:
X(int ii = 0) { p = new int(ii); };
X(const X& obj) { this->p = new int(*(obj.p)); };
// X(X&& obj) { this->p = new int(*(obj.p)); delete obj.p; obj.p=nullptr;
};
X f5() {
return X(5);
}
int main() {
f5() = X(33);
system("pause");
}
Upvotes: 2
Views: 1233
Reputation: 7188
The error message ('X &X::operator =(const X &)': function was implicitly deleted because 'X' has a user-defined move constructor
) clearly answers "yes" to your question. But you apparently want to know the motivation for this rule in C++.
The rule was introduced in C++11 (together with move semantics) to enforce the "Rule of 3/5", which says that all of the following must be used together or not at all:
(in some situations, it is ok to omit move or copy aiir of constructor/assignment).
Similarly, it would make sense to delete the copy assignment operator when a copy constructor is defined, but it could not be done in 2011 to preserve backward compatibility.
Your code is a good illustration of why the Rule of 3/5 is needed. As is, your class leaks memory. If you add a destructor with delete p
, but don't define a move assignment operator, then with your example you get a double deletion (undefined behavior, likely crash).
Finally, note that your move constructor is wrong.
Upvotes: 4
Reputation: 11400
f5() = X(33);
would be calling the assignment operator, because an X object already exists there. It's an assignment, not a construction. Before you had a move constructor, it was calling an auto-generated assignment operator.
Now, the compiler is unwilling (well, forbidden) to generate a default assignment operator because you implement a move constructor. The logic goes, you probably know better about your type, so it will let you implement
X &X::operator =(const X &)
Upvotes: 4