Wednesday, 19 November 2014

Is it possible the destructor be pure virtual in C++?

Is it possible the destructor be pure virtual in C++?

Yes, pure virtual destructors are possible in C++.  When we declare the destructors are pure virtual destructor in the base class we need to provide the empty body for that. Why??? because, we know that the destructor calling sequence is from the most derived class to the base.so, the  derived class destructor will be invoked first and later 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?
C++ compiler & linker enforce existence of function body for pure virtual destructor.
Let us see the below program with the pure virtual function in the base calss with out the body for that and observe the results.

using namespace std;
/*This is my base class */
class MyBaseClass
{
       public:
          MyBaseClass(){ cout << "Constructor of MyBaseClass" << endl;}
          virtual ~MyBaseClass() = 0;
};
/*This is my derived class which is derived from the base*/
class MyDerivedClass: public MyBaseClass
{
     //Doing a lot of jobs by extending the functionality
       public:
           MyDerivedClass(){ cout << "Constructor of MyDerivedClass" << endl; }
           ~MyDerivedClass(){ cout << "Destructor of MyDerivedClass" << endl; }
};
int _tmain (int argc, _TCHAR* argv[])
{
   MyBaseClass *Var = new MyDerivedClass();
    delete Var;
    getchar ();
    return 0;
}

The linker will produce following error in the above program.
 

TestCPP.obj : error LNK2028: unresolved token (0A00085D) "public: virtual __thiscall MyBaseClass::~MyBaseClass(void)" (??1MyBaseClass@@$$FUAE@XZ) referenced in function "public: __thiscall MyDerivedClass::MyDerivedClass(void)" (??0MyDerivedClass@@$$FQAE@XZ)


Now ,provide the definition for the pure virtual destructor, the program compiles & runs without giving any compile & linking errors
using namespace std;
/*This is my base class */
class MyBaseClass
{
       public:
          MyBaseClass();
          virtual ~MyBaseClass() = 0;
};
MyBaseClass::MyBaseClass ()
{
  cout << "Constructor of MyBaseClass" << endl;
}
MyBaseClass::~MyBaseClass ()
{
  cout << "Destructor of MyBaseClass" << endl;
}
/*This is my derived class which is derived from the base*/
class MyDerivedClass: public MyBaseClass
{
     //Doing a lot of jobs by extending the functionality
       public:
           MyDerivedClass() { cout << "Constructor of MyDerivedClass" << endl; }
           ~MyDerivedClass() { cout << "Destructor of MyDerivedClass" << endl; }
};
int _tmain (int argc, _TCHAR* argv[])
{
    MyBaseClass *Var = new MyDerivedClass();
    delete Var;
    getchar ();
    return 0;
}
Output:
Constructor of MyBaseClass
Constructor of MyDerivedClass
Destructor of MyDerivedClass
Destructor of MyBaseClass


NOTE: It is important to note that class becomes abstract class when it contains pure virtual destructor. For example try to compile the below program.
using namespace std;
/*This is my base class */
class MyBaseClass
{
       public:
          MyBaseClass();
          virtual ~MyBaseClass() = 0;
};
MyBaseClass::MyBaseClass ()
{
  { cout << "Constructor of MyBaseClass" << endl; }
}
MyBaseClass::~MyBaseClass ()
{
  { cout << "Destructor of MyBaseClass" << endl; }
}
/*This is my derived class which is derived from the base*/
class MyDerivedClass: public MyBaseClass
{
     //Doing a lot of jobs by extending the functionality
       public:
           MyDerivedClass() { cout << "Constructor of MyDerivedClass" << endl; }
           ~MyDerivedClass() { cout << "Destructor of MyDerivedClass" << endl; }
};
int _tmain (int argc, _TCHAR* argv[])
{
  MyBaseClass *Var = new MyBaseClass ();
    delete Var;
    getchar ();
    return 0;
}


The above program fails in compilation & shows following error messages.
1>  TestCPP.cpp
1>TestCPP.cpp(74): error C2259: 'MyBaseClass' : cannot instantiate abstract class
1>          due to following members:
1>          'MyBaseClass::~MyBaseClass(void)' : is abstract
1>          TestCPP.cpp(44) : see declaration of 'MyBaseClass::~MyBaseClass'
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========



No comments: