Why we need to define the operator or copy constructors as these are system supplied default constructors? Kindly explain this with examples
1 Answer
You need to provide them when you need different behaviour than what the default, compiler provided, functions implement.
The default copy constructor copies all members by value. The default assignment operator assigns all members by value. In a lot of cases this is just what you want so there is no need to provide your own implementations. But that is not always the case.
Consider this contrived example:
struct Broken {
Broken() : i(42), p(new int) { }
~Broken() { delete p; }
int i;
Int* p;
};
It will get the default compiler generated copy ctor and operator= but in this case they don't do what you want - consider this:
int main()
{
Broken b1;
Broken b2 = b1;
} // you'll probably crash here with a double free
What happens is that b1 stores 42 in its i member, then allocates a new int on the heap and stores the address in its p member (let's say the address is 0x1234).
Then we construct b2 from b1 and the default copy constructor happily assigns b2.i to be 42 - this is fine. It also assigns b2.p to have the value 0x1234 - this is not what you want. Now both objects hold a pointer to the same memory and both their destructors will attempt to delete it.
Thus, when b2 goes out of scope at the end of main it disposes of the memory - so far so good - but then b1 also goes out of scope and tries to release the already freed memory and your program is now broken.
In this case you would want to provide your own operator= and copy ctor that don't naively copy the value of the pointer, but instead make a deep copy of whatever the pointer points to and stores that in a new chunk of memory that is distinct from the original, so that both objects have their own unique copy.
There are many other examples but this was the simplest I could come up with.