Pure virtual destructor in C++

来源:互联网 发布:java实现dnf自动刷怪 编辑:程序博客网 时间:2024/05/17 04:04
Do not be anxious about anything, but in everything, by prayer and petition, with thanksgiving, present your requests to god. Philippians 4:6 (Bible)

Can a destructor be pure virtual in C++?
Yes, it is possible to have pure virtual destructor. Pure virtual destructor are legal in standard C++ and one of the most important thing is that if class contains pure virtual destructor it is must to provide a function body for the pure virtual destructor. This seems strange that how a virtual function is pure if it requires a function body? But destructors are always called in the reverse order of the class derivation. That means derived class destructor will be invoked first & then base class destructor will be called. If definition for the pure virtual destructor is not provided then what function body will be called during object destruction? Therefore compiler & linker enforce existence of function body for pure virtual destructor.
Consider following program:

#include <iostream>class Base{public:    virtual ~Base()=0; // Pure virtual destructor};class Derived : public Base{public:    ~Derived()    {        std::cout << "~Derived() is executed";    }};int main(){    Base *b=new Derived();    delete b;    return 0;}

The linker will produce following error in the above program.

test.cpp:(.text$_ZN7DerivedD1Ev[__ZN7DerivedD1Ev]+0x4c): undefined reference to `Base::~Base()' 

Now if the definition for the pure virtual destructor is provided then the program compiles & runs fine.

#include <iostream>class Base{public:    virtual ~Base()=0; // Pure virtual destructor};Base::~Base(){    std::cout << "Pure virtual destructor is called";}class Derived : public Base{public:    ~Derived()    {        std::cout << "~Derived() is executed\n";    }};int main(){    Base *b = new Derived();    delete b;    return 0;}

Output:

~Derived() is executedPure virtual destructor is called

It is important to note that class becomes abstract class when it contains pure virtual destructor. For example try to compile the below program.

#include <iostream>class Test{public:    virtual ~Test()=0; // Test now becomes abstract class};Test::~Test() { }int main(){    Test p;    Test* t1 = new Test;    return 0;}

The above program fails in compilation & shows following error messages.
[Error] cannot declare variable ‘p’ to be of abstract type ‘Test’
[Note] because the following virtual functions are pure within ‘Test’:
[Note] virtual Test::~Test()
[Error] cannot allocate an object of abstract type ‘Test’
[Note] since type ‘Test’ has pure virtual functions

Pure virtual destructor seems to be useless but it is actually not. Pure virtual destructor in a base class forces the derived class to override them. Following is conversation between me & Dr. Bjarne Stroustrup about this topic via mail.

Me: When pure virtual destructor is required?
Dr. Stroustrup: Pure virtual destructor is useful for the usual reason: to force a derived class to override them. You just have to remember to define it also.

Sources:
http://www.bogotobogo.com/cplusplus/virtualfunctions.php
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1905.pdf

This article is contributed Meet Pravasi. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above

0 0