I am reading Chapter 5 of the 2nd edition of A Tour of C++ by Bjarne Stroustrup. He is using an example implementation of Vector to convey his ideas and gets to the move constructor and shows the code but says that the move assignment is similar but doesn't show the code.
A move constructor does not take a const argument: after all, a move constructor is supposed toremove the value from its argument. A move assignment is defined similarly.
class Vector
{
public:
Vector(int sz); // constructor
Vector(const Vector &v); // copy constructor
Vector &operator=(const Vector &v); // copy assignment
Vector(Vector &&v); // move constructor
Vector &operator=(Vector &&v); // move assignment
~Vector(); // destructor
private:
double *elem;
int sz;
};
Vector::Vector(int sz) : elem{new double[sz]}, sz{sz}
{
}
Vector::Vector(const Vector &v) : elem{new double[v.sz]}, sz{v.sz} // copy constructor
{
for (int i = 0; i != sz; ++i)
{
elem[i] = v.elem[i];
}
}
Vector &Vector::operator=(const Vector &v) // copy assignment
{
double *p = new double[v.sz];
for (int i = 0; i != v.sz; ++i)
{
p[i] = v.elem[i];
}
delete[] elem; // delete all elements
elem = p;
sz = v.sz;
return *this;
}
Vector::~Vector()
{
delete[] elem;
}
Vector::Vector(Vector &&v) // move constructor
: elem{v.elem},
sz{v.sz}
{
v.elem = nullptr;
v.sz = 0;
}
Is this the correct move assignment operator?
Vector &Vector::operator=(Vector &&v)
{
elem = v.elem;
sz = v.sz;
v.elem = nullptr;
v.sz = 0;
return *this;
}
How would I be able to check that a move and not a copy was made if both constructors exist?
No, it's not since it will make the program leak any memory already allocated by
*this. Normally, you'd also want your move constructor and move assignment operator to benoexcept.You could also check for self-assignment (
if (this == &v) return *this;) to make self-assignment into a no-op. Thendelete[] elem;beforeelem = v.elem;...... or
std::swapthe memory withvand letvfree it when it is destroyed: