Posted by: rmn on: 04/09/2009
Many times we are required to define both a copy constructor and an assignment operator (for example: according to the rule of three, if we need one we are likely to need the other). The two will probably share a pretty common code, if not exactly the same. So what we will do in many cases is export the code to a private method which will be called from both the constructor and the assignment operator, effectively giving up on initialization list benefits in the constructor, or duplicating code.
A pretty nice way to overcome this is by implementing the assignment operator in terms of the copy constructor. However, I will explain later why this suggested way is not really recommended to use.
Have a look at the proposed implementation:
#include <new.h>
struct A {
A ();
A (const A &a);
virtual A &operator= (const A &a);
virtual ~A ();
};
A &A::operator= (const A &a) {
if (this != &a) {
this->A::~A(); // explicit non-virtual destructor
new (this) A(a); // placement new
}
return *this;
}
A very important point to take notice of in this implementation is that there’s an explicit call to A’s destructor (not through the virtual dispatching mechanism) – why is that so important, you ask? Since otherwise we’d be calling the virtual destructor, thereby destructing the whole possibly polymorphic object (that can be bigger than A), but only constructing a new A object in its place – hazardous!
Why don’t I recommend using this method?
I’d actually favor a virtual destructor in this context. In a scenario like:
class D : public A
{
…
int iExtraState;
…
}
A a;
D d;
…
d = a;
In your implementation, the last call destroys and replaces only the A subobject, and leaves d’s extra-state in a state that is most probably inconsistent with it. This can be a hard bug to track.
Seems much safer to call the virtual destructor and clean the entire object. If you do need to set only the A-subobject state, the reasonable thing to do would be to create a dedicated interface. Assignment is implicitly assumed to leave the object in a consistent state (as was the copied object).
08/09/2009 at 21:14
See:
http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Copy-and-swap