Scott said on Effective C++, 3rd Edition, pg. 43 that to make an abstract class, we just need to give it a pure virtual destructor:
class AWOV { // AWOV = "Abstract w/o Virtuals" public: virtual ~AWOV() = 0; // declare pure virtual destructor };
Then, he went on said that there is one twist: we must provide a definition for the pure virtual destructor:
AWOV::~AWOW() {} // definition of pure virtual dtor
My question is, by specifiying = 0
, for pure virtual functions, we are saying that the function cannot have any definition for the class where this pure virtual function is declared.
Why is it OK to provide a definition (even it is empty) for the pure virtual destructor here?
A pure virtual function is a function that must be overridden in a derived class and need not be defined.
Why use virtual functions. We use virtual functions to ensure that the correct function is called for an object, regardless of the reference type used to call the function. They are basically used to achieve the runtime polymorphism and are declared in the base class by using the virtual keyword before the function.
A pure virtual function or pure virtual method is a virtual function that is required to be implemented by a derived class if the derived class is not abstract. Classes containing pure virtual methods are termed "abstract" and they cannot be instantiated directly.
A pure virtual function is a member function of base class whose only declaration is provided in base class and should be defined in derived class otherwise derived class also becomes abstract. Classes having virtual functions are not abstract. Base class containing pure virtual function becomes abstract.
"we are saying that the function cannot have any definition for the class where this pure virtual function is declared."
That's not what pure virtual means. Pure virtual only means that the containing class cannot be instantiated (is abstract), so it has to be subclassed, and subclasses must override the method. E.g.,
struct A { virtual ~A() = 0; }; A::~A() {} struct B : A {}; int main() { A a; // error B b; // ok }
Here, the B
destructor is implicitly defined. If it was another method that is pure virtual, you'd have to explicitly override it:
struct A { virtual void foo() = 0; }; void A::foo() {} struct B : A {}; int main() { B b; // error }
Providing a definition for a pure virtual method is desirable when the base class must be abstract but still provide some default behavior.
In the specific case of a destructor, it has to be provided because it will be called automatically when subclass instances are destroyed. A program that tries to instantiate a subclass of a class with a pure virtual destructor without a definition will not pass the linker.
Making it pure forces derived (non-abstract) classes to implement their own.
Providing an implementation allows derived classes to invoke base class behavior (which destructors do by default).
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