Re: Okay to move an object?
Frederick Gotham wrote:
(Before I begin, please don't suggest to me to use "std::vector" rather
than actual arrays.)
I understand that an object can have resources (e.g. dynamically
allocated memory), and so we have to copy an object properly via copy-
construction rather than using memcpy.
However, is it okay to move an object manually (i.e. by using memcpy or
memmove)?
Not in general, because objects may be entangled in relationships which
are hinged on their address.
An object may contain pointers to parts of itself. For instance, an
object representing a buffered I/O stream over a file might contain a
buffer, as well as a pointer to the current read position within the
buffer rather than an index. If you copy the object, its pointer still
points within the original object.
There may be other objects which know about that object, and refer to
it by its address. For instance, a node in a binary tree has a parent
which points to it via a child pointer. A naive copy of the object will
retain that parent, but that parent still points to the original object
as its child. Treating this node as the root of a subtree could wreck
the original tree, depending on what kind of operation is attempted.
C++ polymorphic objects may have this kind of information in them, as a
way of implementing the object system. For instance, the derived part
of an object could have a hidden back-pointer to a base class part or
vice versa. So you cannot treat these types of objects as raw memory to
be copied around.
Even plain C-like structures cannot necessarily be treated that way.
Although the C++ implementation may allow a bit copy, whether or not
that makes sense still depends on the meaning of that data type and how
it relates to other data.
For instance FILE streams in the Standard C library are not C++
classes, but it's still forbidden to copy them.
Another example is the va_list type, which can only be copied by
va_copy, not by assignment.
Only thing I can see which could make things go awry is if the object
kept its own address stored within it for some reason.
Or if that object is part of a larger data structure which knows about
that object's address!
Imagine if you populated the array with the nodes of a binary tree and
ran your sorting algorithm. It would scramble the link pointers within
that tree, destroying the whole thing.
You'd have to run some kind of "tree repair" afterward to rebuild the
structure. But then your sorting algorithm would no longer be generic:
it would work specifically with objects which may be bitwise copied
/provided/ that a special fixup is invoked afterward.
C++ doesn't provide any standard way to fix up the internal information
of class objects which may have such information (i.e. other than
"plain old datatypes").