在析构函数之前省略关键字virtual仍然可以虚拟地工作

时间:2017-09-15 03:27:10

标签: c++ virtual destructor

#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;
}

我的问题是,如果我不在析构函数前面写关键字virtual,那么上面的代码工作正常,那为什么是虚拟析构函数?

2 个答案:

答案 0 :(得分:1)

此代码中没有任何内容需要虚拟析构函数,因此确实可以正常工作。如果通过指向基类型的指针删除派生类型的对象,则需要虚拟析构函数。像这样:

Mahesh *m1 = new Purnima;
delete m1;

如果Mahesh的析构函数不是虚拟的,则此代码具有未定义的行为。注意:未定义行为最阴险的表现之一是代码&#34;工作正常&#34;,直到你在其他地方做了一些小改动,为你最重要的客户做准备,此时它将失败了。

答案 1 :(得分:0)

当你编写像这样的代码时

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

   return 0;
}

当你超出范围时,你会自动销毁Purnima p1 ..这就是为什么你得到适当的析构函数序列调用。

无论如何,你无法删除m1,否则会崩溃。

尝试将其封闭在范围内以便更好地理解它。

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

   return 0;
}
在析构函数调用之后,将打印“在Scope之后”。

简而言之,在处理动态类型时需要virtual