#Move constructors and instances

12 messages · Page 1 of 1 (latest)

jolly grove
#

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?

jaunty brambleBOT
#

When your question is answered use !solved or the button below to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.

marsh silo
#

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?
Yes

#

But what if most of my objects contain mostly just references to other, possibly big objects? Is there any sense in move semantics there
No. So don't write a custom move operations and let the compiler generate them

#

Even if you have something like

struct A
{
    std::vector<int> vec;
};

Even if the vector is large, this doesn't need custom move operations, since the implicitly generated ones will already do the right thing, which is calling the respective move operation on vec

#

Only custom containers and similar classes need the custom ones

#

Does it mean move semantics are useless for stack allocated objects?
What does this have to do with the stack? If you have a large vector on the stack, you might want to move it somewhere

jolly grove
marsh silo
#

The data is on the heap, but the vector itself (a few pointers) is on the stack. But ok, I see what you mean

#

Another usecase for move semantics is dealing with things like file handles (FILE *), which can't be copied but can reasonably be moved

#

A lot of C libraries deal out similar handles that you might wanna wrap in move-only classes

jolly grove
#

Yeah I get it now I think. I work in C++ for years but somehow I thought move semantics optimize away even the instance creation (similarly to RVO/NRVO).