1
#include<iostream>
using namespace std;

class Mahesh
{

   public:
      Mahesh(){
         cout<<"Base Constructor is called at here"<<endl<<endl;
      }
      virtual ~ Mahesh()
      {
         cout<<"Base Destructor is called"<<endl<<endl;
      }
};

class Purnima:public Mahesh
{

   public:

      Purnima()
      {
         cout<<"Derived class constructor"<<endl<<endl;
      }
      ~Purnima(){
         cout<<"Derived class Destructor"<<endl<<endl;
      }
};

int main()
{
   Mahesh *m1;
   Purnima p1;
   m1=&p1;

   return 0;
}

My question is if I don't write keyword virtual in front of destructor then above code works fine, then why virtual destructor?

dlmeetei
  • 9,905
  • 3
  • 31
  • 38
  • 1
    Better duplicate: https://stackoverflow.com/q/461203/501250 – cdhowie Sep 15 '17 at 03:35
  • 4
    Neither duplicate is appropriate. The answer is that `virtual` is inherited, whether you re-specify it in the derived destructor or not. – user207421 Sep 15 '17 at 03:55
  • 3
    You never even invoke the destructor polymorphically. You're essentially testing that destroying a derived class calls both the parent and derived destructors. – chris Sep 15 '17 at 03:59
  • The virtual destructor makes a difference if you write `m1 = new Purnima; delete m1;` – M.M Sep 15 '17 at 04:13
  • Omitting the keyword in a derived class makes no difference: https://stackoverflow.com/questions/4895294/c-virtual-keyword-for-functions-in-derived-classes-is-it-necessary But you don't even need virtual in the base class in your example. – juanchopanza Sep 15 '17 at 06:46

2 Answers2

1

Nothing in this code requires a virtual destructor, so it does, indeed, work fine. You need a virtual destructor if you delete an object of a derived type through a pointer to the base type. Like this:

Mahesh *m1 = new Purnima;
delete m1;

If the destructor of Mahesh is not virtual, this code has undefined behavior. Beware: one of the most insidious manifestations of undefined behavior is that the code "works fine", until you make a slight change somewhere else, in preparation for a demo to your most important client, at which point it will fail disastrously.

Pete Becker
  • 74,985
  • 8
  • 76
  • 165
  • You forgot to mention that, once the problem becomes evident, the time needed to find the cause is negatively correlated with the amount of time available to fix it. The less time you have, the more you need. :-) – Peter Sep 15 '17 at 13:03
0

When you write the code like this

int main()
{
   Mahesh *m1;
   Purnima p1;
   m1=&p1;

   return 0;
}

You get Purnima p1 destructed automatically when you get out of scope.. that's why you get appropriate destructor sequence call.

Anyway you can't delete the m1 otherwise its a crash.

Try enclosing inside the scope to understand it better.

int main()
{
   {
     Mahesh *m1;
     Purnima p1;
     m1=&p1;
   }
   cout<<"After Scope.."<<endl;

   return 0;
}

"After Scope" shall be printed after destructor call.

So in a nutshell, you need virtual when dealing with dynamic types

Daksh Gupta
  • 7,554
  • 2
  • 25
  • 36
  • I had a similar thought to this when I wondered what happens if you assign a unique_ptr to point to a local variable. Turns out they're not COMPLETELY idiot-proof. – Zebrafish Sep 15 '17 at 13:53