What "copying an object" actually means.
copy constructor, copy assignment operator, and destructor are special member functions.
the rule of three
Consider the situation where a class manages a resource, such a class needs to implement The Big Three (because the default copy constructor and copy assignment operator do not work in this case).
Here we focus on copy constructor and copy assignment operator.
Can we also have a move assignment operator?
Yes, we do, but not always.
Consider the following code snippet:
class A {
// this class has to manage a resource such as a manually allocated memeroy block
A& operator= (A other) {
swap(*this, other);
return *this;
}
A& operator=(A &&other) {
swap(*this, other);
return *this;
}
};An rvalue of type A binds to both parameters equally well. So there is an overload ambiguity.
So this means if we implement the copy assignment operator mannully with the copy-and-swap idiom, then we cannot have a move assignment operator.
Actually, this is non-issue. If we have implemented the move constructor, then it's enough to add a copy assignment operator with its source argument passed by value (as the case of copy-and-swap idiom).
Let's demonstrate the idea in code.
class A {
swap(A &a, A &b) {
// swap function for copy-and-swap idiom
}
A(const A& other) {
// a well-implemented copy constructor
}
A(A&& other)
: A() // initialize via default constructor, since C++11
{
swap(*this, other);
}
A& operator=(A other) {
swap(*this, other);
return *this;
}
};
A a;
b = expr_return_an_A;Here is the analysis.
If expr_return_an_A returns an lvalue then the argument of A::operator= is copy constructed, if it returns an rvalue the argument is move constructed, and sometimes the move construction is hopefully elided. There is no significant overhead in either case.