1

I have a constructor that looks like this:

Thing::Thing(std::vector<uint8> & data){
    m_data = data; // m_data is also a vector<uint8>
    // do other stuff
}

However, data holds a pretty large chunk of memory, and instead of copying it, I'd like data to simply give it up to m_data, as the caller will never need it after constructing this object. What's the best way to do this in C++?

Anne Quinn
  • 12,609
  • 8
  • 54
  • 101

1 Answers1

6

You can use the move assignment operator.

m_data = std::move(data);

It will be better to change the argument type to a value or an rvalue reference so that the user of the function is not surprised that the contents of the input argument have been moved.

Thing::Thing(std::vector<uint8>&& data){
    m_data = std::move(data);
    // do other stuff
}

Given that, the calling function will be aware that they need to pass an rvalue reference and won't be surprised by the move of the contents.

It will be better to initialize m_data using data instead of assigning to it.

Thing::Thing(std::vector<uint8>&& data) : m_data(std::move(data))
{
    // do other stuff
}
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • 2
    Please suggest they pass by value or rvalue reference. Otherwise it's not clear ownership is being transferred. Also, as a constructor you should use the class member initialization list. – NathanOliver Jul 25 '19 at 20:07
  • @NathanOliver, thanks for the suggestion. – R Sahu Jul 25 '19 at 20:11
  • 1
    `m_data = data;` will make a copy since `data` is an lvalue. – NathanOliver Jul 25 '19 at 20:12
  • @NathanOliver, even if the argument is of type `td::vector&&`? – R Sahu Jul 25 '19 at 20:13
  • 1
    Yep. Anything with a name is a lvalue. You need `Thing::Thing(std::vector&& data){ m_data = std::move(data); // do other stuff }` or `Thing::Thing(std::vector&& data) : m_data(std::move(data)) { //do stuff }` – NathanOliver Jul 25 '19 at 20:14
  • @NathanOliver, thanks. I am yet to master move semantics. – R Sahu Jul 25 '19 at 20:15
  • 1
    I gave it a try, and apparently yes, you do need `std::move()` in both the constructor and the constructor argument, if I did it correctly https://onlinegdb.com/rkGSecwzr – Anne Quinn Jul 25 '19 at 20:26