The default move constructor and move asignment generated by the compiler will call move constructor/asignment for each member of the class.
If your class has only raw members, "char * buffer" for example, you have to write your own move operations.
If your class has only "managed members", "vector" for example, default move operations for you class will be ok because it delegates the operation to each member.
If your class has "managed members" mixed with "raw members", vector and int* for example, your movement operations will have to do the manual move of raw resources and call move operations for managed objects:
class MyObject {
public:
// ...
MyObject(MyObject&& other) : vector1(std::move(other.vector1)) {
// We use vector's move constructor ^
// and then move ourself the char* buffer
buffer1 = other.buffer1;
other.buffer1 = nullptr;
}
MyObject& operator=(MyObject&& other) {
// We use vector's move asignment operator
vector1= std::move(other.vector1);
// and then move ourself the char* buffer
std::swap(buffer1,other.buffer1);
return *this;
}
//...
private:
vector<char> vector1;
char * buffer1;
};
std::move(other.vector1) is needed because inside that function other.vector1 is an lvalue. We have to tell the compiler we will not use vector1 value later in the function code so it's value can be moved.