2

I have written a move constructor for a class in the following way:

class A { std::vector<double> m; A(A&& other) : m{other.m} { } } 

Is this the correct way to move other.m to m?

Should I be doing this instead?

A(A&& other) : m{std::move(other.m)} { } 

Or perhaps I should be doing something else entirely?

1
  • 1
    You should leave it default. Rule of Zero. Commented Mar 6, 2016 at 18:00

2 Answers 2

1

The second snippet is the correct way to move other.m since it's a lvalue that needs to be turned into r-value-reference for std::vector move constructor to kick in.

even though, in this very specific example, it will be enough to simply write

A(A&& rhs) = default; 

the compiler will generate a constructor that moves each member of rhs to the corresponing member of *this.

p.s. you also probably meant to make the constructor public.

Sign up to request clarification or add additional context in comments.

2 Comments

I prefer to write them manually for practice, often I have classes where there will be non-trivial move/copy constructors/assignments. Do I have to use std::move in the move assignment operator? At the moment, I'm just using std::swap? Perhaps I should ask this as a separate question?
you should use std::move on variables with names if you want to move them around. it doesn't matter what function it is.
0
/****************************************************************************** Below program demonstrates how to use move constructor and move assignment operator *******************************************************************************/ #include <iostream> #include <algorithm> #include <vector> class MemoryBlock { public: MemoryBlock() { this->id++; std::cout << "Default Constructor"<<std::endl; } // Simple constructor that initializes the resource. explicit MemoryBlock(size_t length) : _length(length) , _data(new int[length]) { this->id++; std::cout << "Constructor In MemoryBlock(size_t). length = and id =" << _length << "." <<id<< std::endl; } // Destructor. ~MemoryBlock() { this->id--; std::cout << "Destructor In ~MemoryBlock(). length = and id =" << _length << "."<<id; if (_data != nullptr) { std::cout << " Deleting resource."; // Delete the resource. delete[] _data; } std::cout << std::endl; } // Copy constructor. MemoryBlock(const MemoryBlock& other) : _length(other._length) , _data(new int[other._length]) { this->id++; std::cout << " Copy Constructor MemoryBlock(const MemoryBlock&). length = and id =" << other._length << "." <<id<<"Copying resource." << std::endl; std::copy(other._data, other._data + _length, _data); } // Copy assignment operator. MemoryBlock& operator=(const MemoryBlock& other) { std::cout << "Assignment operator In operator=(const MemoryBlock&). length = " << other._length << ". Copying resource." << std::endl; if (this != &other) { // Free the existing resource. delete[] _data; _length = other._length; _data = new int[_length]; std::copy(other._data, other._data + _length, _data); } return *this; } // Retrieves the length of the data resource. size_t Length() const { return _length; } //Move copy constructor MemoryBlock(MemoryBlock&& other) noexcept : _data(nullptr) , _length(0) { std::cout << "Move Constructor In MemoryBlock(MemoryBlock&&). length = " << other._length << ". Moving resource." << std::endl; // Copy the data pointer and its length from the // source object. _data = other._data; _length = other._length; // Release the data pointer from the source object so that // the destructor does not free the memory multiple times. other._data = nullptr; other._length = 0; } // Move assignment operator. MemoryBlock& operator=(MemoryBlock&& other) noexcept { std::cout << "Move assignment operator In operator=(MemoryBlock&&). length = " << other._length << "." << std::endl; if (this != &other) { // Free the existing resource. delete[] _data; // Copy the data pointer and its length from the // source object. _data = other._data; _length = other._length; // Release the data pointer from the source object so that // the destructor does not free the memory multiple times. other._data = nullptr; other._length = 0; } return *this; } private: size_t _length; // The length of the resource. int* _data; // The resource. static int id; }; int MemoryBlock::id=0; int main() { std::vector<MemoryBlock> v1; MemoryBlock m1(100); MemoryBlock m2(100); MemoryBlock m3(100); v1.push_back(m1); v1.push_back(m2); v1.push_back(m3); return 0; } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.