I am currently trying to figure out how to do move semantics correctly with an object which contains a pointer to allocated memory. I have a big datastructure, which contains an internal raw pointer to the actual storage (for efficiency reasons). Now I added a move constructor and move operator=()
. In these methods I am std::move()
ing the pointer to the new structure. However I am not sure what to do with the pointer from the other structure.
Here is a simple example of what I am doing:
class big_and_complicated {
// lots of complicated code
};
class structure {
public:
structure() :
m_data( new big_and_complicated() )
{}
structure( structure && rhs ) :
m_data( std::move( rhs.m_data ) )
{
// Maybe do something to rhs here?
}
~structure()
{
delete m_data;
}
private:
big_and_complicated * m_data;
}
int main() {
structure s1;
structure s2( std::move( s1 ) );
return 0;
}
Now from what I understand, after the std::move( s1 )
to s2
the only thing that is safe to do on s1
ist to call its constructor. However as far as I can see, this would lead to deleting the pointer contained within s1
in the destructor, rendering s2
useless as well. So I am guessing I have to do something to render the destructor safe when std::move()
ing the pointer. As far as I can see the safest thing to do here, is to set it to 0
in the moved object, since this would turn the delete
into a no-op later on. Is this reasoning correct so far? Or is std::move()
actually smart enough to null out the pointer for me, rendering its usage safe? So far I am seeing no crashes in the actual test-suite, but I have not made sure the move-constructor is actually called.
"Moving" a pointer is no different than copying one and does not set the moved-from value to null ('moving' is in quotes here because
std::move
does not move anything really, it just changes the value category of the argument). Just copyrhs
' pointer then set it tonullptr
:Better yet, use
std::unique_ptr<big_and_complicated>
instead ofbig_and_complicated*
and you don't need to define any of this yourself:Lastly, unless you actually want
structure
to remain non-copyable, you're better off just implementing proper move semantics inside ofbig_and_complicated
and havingstructure
hold abig_and_complicated
object directly.