Copy Constructors and Assignment Operators in Derived Classes in C++
Providing a copy constructor and assignment operator is a must when you have dynamically allocated memory in a class. When defining a derived class, you need to be careful about copy constructors and operator=
.
If your derived class does not have any special data (pointers, usually) that require a nondefault copy constructor or operator=
, you don't need to have one, regardless of whether the base class has one. If your derived class omits the copy constructor or operator=
, a default copy constructor or operator=
will be provided for the data members specified in the derived class, and the base class copy constructor or operator=
will be used for the data members specified in the base class.
On the other hand, if you do specify a copy constructor in the derived class, you need to explicitly call the parent copy constructor, as shown in the following code. If you do not do this, the default constructor (not the copy constructor!) will be used for the parent portion of the object.
class Base { public: virtual ˜Base() = default; Base() = default; Base(const Base& src) { /* SOME CODE */ }; }; class Derived : public Base { public: Derived() = default; Derived(const Derived& src) : Base { src }{ /* SOME CODE */ } };
Similarly, if the derived class overrides operator=
, it is almost always necessary to call the parent's version of operator=
as well. The only case where you wouldn't do this would be if there was some bizarre reason why you only wanted part of the object assigned when an assignment took place. The following code shows how to call the parent's assignment operator from the derived class:
Derived& Derived::operator=(const Derived& rhs) { if (&rhs == this) { return *this; } Base::operator=(rhs); // Calls parent's operator=. // Do necessary assignments for derived class. return *this; }
NOTE: When you need copy functionality in an inheritance hierarchy, a common idiom employed by professional C++ developers is to implement a polymorphic clone()
member function, because relying on the standard copy constructor and copy assignment operators is not sufficient.