How does the move constructor work in C ++?

I read a lot of articles about the move constructor (even on the stack), but I couldn’t find an exact explanation of how this works (how a pointer to a temporary object is transferred and saved if this temporary variable and its address are destroyed upon meeting ")") .

Here is a simple example

#include <iostream> #include <vector> using namespace std; class boVector { private: int size; public: boVector() {}; boVector(const boVector& rhs) { cout << "copy Ctor." << endl; } boVector(boVector&& rhs) { cout << "move Ctor." << endl; } }; void foo(boVector v) {} boVector createBoVector() { return boVector(); } int main() { //copy boVector reausable = createBoVector(); foo(reausable); //move foo(std::move(createBoVector())); return 0; } 

Everyone says that the Ctor movement is a shallow copy or just a pointer assignment. But how can I initiate my object with a pointer to a temporary object (when this object is destroyed, my object will point to an unknown address, and this is not valid from my point of view).

It is incorrect to initiate a variable with the address of the pointer, which will no longer exist after its matching ")".

Please, if someone explains to me what this temporary variable looks like in memory and how you can assign the address of a temporary object to my current one, and this operation will be valid.

+5
source share
2 answers

A "move constructor" is not magic - it is a constructor that accepts an rvalue reference.

Rvalue references are attached to a temporary object and have a “value” for something that expires and which will not be accessed in the future: this allows developers to implement moves for resource classes in terms of pointer swaps or similar quick operations.

Your boVector class cannot take any advantage of the movement semantics, as it simply stores an int and does not contain any resource. Moving an int is as fast as copying.


IN

 foo(std::move(createBoVector())); 

std::move is redundant since createBoVector() already an rvalue.


Consider:

 foo(createBoVector()); 

This will call boVector(boVector&&) as it is better than boVector(const boVector&) .

The instance created by createBoVector() will live for the duration of the expression - this means that the rvalue reference will point to a valid object during boVector(boVector&&) .

+10
source

Everyone says that the Ctor movement is a shallow copy or just a pointer assignment.

Not everyone says that this is not so. A move constructor is what you define it. In your example, your ctor movement does something completely different. The ctor move point — unlike the ctor copy — is that you know that another object is about to be destroyed, so you can cannibalize or move its resources.

The move constructor can make a “shallow copy”, although this term is colloquial and not clearly defined in C ++. "Just a pointer assignment" - perhaps, perhaps, sometimes.

But how can I initiate my object with a pointer to a temporary object (when this object is destroyed, my object will point to an unknown address, and this is not valid from my point of view).

You do not (usually) initialize an object of type T pointer of type T* , as such. You can assign my_t = *my_t_ptr , or if you know you cannibalize the T pointed to by my_t_ptr since it will be deleted soon, then you can assign my_t = std::move(*my_t_ptr) .

Can you give me a more suitable example [of a significant difference between the move constructor and the copy constructor] ...?

A “classic” example is when your T is created by allocating some space on the heap. When you copy-build one T from another, you have no choice but to allocate a second piece of memory; when you move-build a T , you can: 1. copy the pointer from the existing T to T 2. Set the existing T element pointer to nullptr . In this case, you always use only the stock space T

+2
source

Source: https://habr.com/ru/post/1274761/


All Articles