What could possibly be in the class that absolutely needs a copy constructor and cannot be moved. |
Lots of things. Reference counts and allocated buffers come to mind first. But there can be other things, like pointers to member buffers, iterators, etc.
Consider the following:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
class A
{
public:
// default ctor
A() : buf( new int[20] ) { }
// default dtor
~A() { delete[] buf; }
// copy ctor
A(const A& a) : buf(new int[20])
{ *this = a; }
// assignment operator
A& operator = (const A& a)
{ /*... copy a.buf contents to this->buf here -- too lazy to write code*/ }
private:
int* buf;
};
|
As you can see --- the copy constructor here is responsible for allocating a new buffer. If you simply memcpy'd or memmove'd the data instead of calling the copy ctor, two objects would point to the same buffer, and they'd both try to delete the same buffer!
The assignment operator is similar. Simply copying the data would not copy the buffers themselves, it would just copy the pointer (so you'd have the same problem -- two objects would have the same pointer, and they'd both try to delete the same buffer on their destruction).
EDIT:
I mean, when you push_back and the vector must be enlarged, they just realloc right ? they don't malloc a new one and copy construct all the elements. |
If the memory buffer needs to be enlarged, then vector
will create all new objects by using the copy ctor, then destroy the originals. It can have quite significant overhead if you are irresponsible with it.
Same thing when you remove elements in the middle of the vector. It has to shift all of the other elements forward to close the gap that's created -- and to do that it has to copy the objects and destroy all the originals. This is why it's so undesirable to do that with a vector.