Let's assume we have a very basic class A
:
class A { public: void SetName(const std::string& newName) { m_name=newName; } void Print() const { std::printf("A::Print(). Name: %s\n",m_name.c_str()); } private: std::string m_name; };
We want to extend this class with class B
so we add our virtual destructor, change a member to virtual
and change private
to protected
for inh:
class A { public: virtual ~A() {} void SetName(const std::string& newName) { m_name=newName; } virtual void Print() const { std::printf("A::Print(). Name: %s\n",m_name.c_str()); } protected: std::string m_name; }; class B : public A { public: virtual void Print() const { std::printf("B::Print(). Name: %s\n",m_name.c_str()); } };
Now since we added a destructor in class A
do we need to create a copy constructor and copy operator like so?
class A { public: virtual ~A() {} A() = default; A(const A& copyFrom){ *this = copyFrom; } virtual A& operator=(const A& copyFrom){ m_name=copyFrom.m_name; return *this; }; void SetName(const std::string& newName) { m_name=newName; } virtual void Print() const { std::printf("A::Print(). Name: %s\n",m_name.c_str()); } protected: std::string m_name; };
To me this seems unnecessary as the default copy operator and copy constructor would do the same thing.
Yes, they are the same. The derived class not declaring something virtual does not stop it from being virtual. There is, in fact, no way to stop any method (destructor included) from being virtual in a derived class if it was virtual in a base class.
Technically, destructors ARE inherited. But in normal circumstances, the inherited destructors are not directly used for a derived class; they're invoked because the derived class's own destructor calls them in order to destroy its own "base class subobjects" as a step within destroying the larger object.
The rule of three and rule of five are rules of thumb in C++ for the building of exception-safe code and for formalizing rules on resource management. The rules prescribe how the default members of a class should be used to achieve these goals systematically.
The following restrictions apply to constructors and destructors: Constructors and destructors do not have return types nor can they return values. References and pointers cannot be used on constructors and destructors because their addresses cannot be taken. Constructors cannot be declared with the keyword virtual .
To be prepared for potential future evolution of the language, you should indeed explicitly default the copy/move constructors and assignment operators when you add a virtual destructor. That's because C++11, 12.8/7 makes implicit generation of copy constructors deprecated when the class has a user-declared destructor.
Fortunately, C++11's explicit defaulting makes their definition easy:
class A { public: virtual ~A() {} A() = default; A(const A& copyFrom) = default; A& operator=(const A& copyFrom) = default; A(A &&) = default; A& operator=(A &&) = default; void SetName(const std::string& newName) { m_name=newName; } virtual void Print() const { std::printf("A::Print(). Name: %s\n",m_name.c_str()); } protected: std::string m_name; };
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With