For most times I used move semantics to ensure that data allocated on heap (containers like std::vector, std::unordered_map, owners like std::unique_ptr) is not copied, but its owner is replaced.
However, I feel like I'm not too confident in that matter when it comes to writing move constructors of my own classes. Here's some code I'm tinkering with: https://godbolt.org/z/6b659bvno
Do I understand correctly that move constructor initializes a new instance of the object, but the convention is it behaves differently when it comes to members - especially with heap-allocated members - than the copy constructor? That means, they change the owner and leave original object with nullified/zeroed pointer or value, when copy constructor should copy that memory - whole string or vector - leaving original without any changes.
But what if most of my objects contain mostly just references to other, possibly big objects? Is there any sense in move semantics there, since such a move constructor won't change the reference in moved-from object and the reference will be copies to the move-to object? It looks like a simple copy constructor would do the same. Does it mean move semantics are useless for stack allocated objects?
In terms of the shared code example above, does this mean this whole application have no sense if some of the classes (A, B, AA or BB) won't be extended to contain heavy, heap-allocated variables?