I have a medium complex C++ class which holds a set of data read from disc. It contains an eclectic mix of floats, ints and structures and is now in general use. During a m
The most common reason to explicitly define an assignment operator is to support "remote ownership" -- basically, a class that includes one or more pointers, and owns the resources to which those pointers refer. In such a case, you normally need to define assignment, copying (i.e., copy constructor) and destruction. There are three primary strategies for such cases (sorted by decreasing frequency of use):
Deep copy means allocating a new resource for the target of the assignment/copy. E.g., a string class has a pointer to the content of the string; when you assign it, the assignment allocates a new buffer to hold the new content in the destination, and copies the data from the source to the destination buffer. This is used in most current implementations of a number of standard classes such as std::string
and std::vector
.
Reference counting used to be quite common as well. Many (most?) older implementations of std::string
used reference counting. In this case, instead of allocating and copying the data for the string, you simply incremented a reference count to indicate the number of string objects referring to a particular data buffer. You only allocated a new buffer when/if the content of a string was modified so it needed to differ from others (i.e., it used copy on write). With multithreading, however, you need to synchronize access to the reference count, which often has a serious impact on performance, so in newer code this is fairly unusual (mostly used when something stores so much data that it's worth potentially wasting a bit of CPU time to avoid such a copy).
Transfer of ownership is relatively unusual. It's what's done by std::auto_ptr
. When you assign or copy something, the source of the assignment/copy is basically destroyed -- the data is transferred from one to the other. This is (or can be) useful, but the semantics are sufficiently different from normal assignment that it's often counterintuitive. At the same time, under the right circumstances, it can provide great efficiency and simplicity. C++0x will make transfer of ownership considerably more manageable by adding a unique_ptr
type that makes it more explicit, and also adding rvalue references, which make it easy to implement transfer of ownership for one fairly large class of situations where it can improve performance without leading to semantics that are visibly counterintuitive.
Going back to the original question, however, if you don't have remote ownership to start with -- i.e., your class doesn't contain any pointers, chances are good that you shouldn't explicitly define an assignment operator (or dtor or copy ctor). A compiler bug that stopped implicitly defined assignment operators from working would prevent passing any of a huge number of regression tests.
Even if it did somehow get released, your defense against it would be to just not use it. There's no real room for question that such a release would be replaced within a matter of hours. With a medium to large existing project, you don't want to switch to a compiler until it's been in wide use for a while in any case.
If the compiler isn't generating the assignment properly, then you have bigger problems to worry about than implementing the assignment overload (like the fact that you have a broken compiler). Unless your class contains pointers, it is not necessary to provide your own overload; however, it is reasonable to request an explicit overload, not because the compiler might break (which is absurd), but rather to document your intention that assignment be permitted and behave in that manner. In C++0x, it will be possible to document intent and save time by using = default
for the compiler-generated version.
I guess the problem of shallow copy deep copy may appear in case you are dealing with strings. http://www.learncpp.com/cpp-tutorial/912-shallow-vs-deep-copying/
but i think it is always advisable to write assignment overloads for user defined classes.
It is well-known what the automatically-generated assignment operator will do - that's defined as part of the standard and a standards-compliant C++ compiler will always generate a correctly-behaving assignment operator (if it didn't, then it would not be a standards-compliant compiler).
You usually only need to write your own assignment operator if you've written your own destructor or copy constructor. If you don't need those, then you don't need an assignment operator, either.
If you have some resources in your class that you are supposed to manage then writing your own assignment operator makes sense else rely on compiler generated one.