为什么要用“虚析构函数”?

转载 2011年10月24日 14:58:10

 析构函数的工作方式是:

      最底层的派生类(most   derived   class)的析构函数最先被调用,然后调用每一个基类的析构函数。

      因为在C++中,当一个派生类对象通过使用一个基类指针删除,而这个基类有一个非虚的析构函数,则结果是未定义的。运行时比较有代表性的后果是对象的派生部分不会被销毁。然而,基类部分很可能已被销毁,这就导致了一个古怪的“部分析构”对象,这是一个泄漏资源。排除这个问题非常简单:给基类一个虚析构函数。于是,删除一个派生类对象的时候就有了你所期望的正确行为。将销毁整个对象,包括全部的派生类部分。

      但是,一般如果不做基类的类的析构函数一般不声明为虚函数,因为虚函数的实现要求对象携带额外的信息,这些信息用于在运行时确定该对象应该调用哪一个虚函数。典型情况下,这一信息具有一种被称为   vptr(virtual   table   pointer,虚函数表指针)的指针的形式。vptr   指向一个被称为   vtbl(virtual   table,虚函数表)的函数指针数组,每一个包含虚函数的类都关联到   vtbl。当一个对象调用了虚函数,实际的被调用函数通过下面的步骤确定:找到对象的   vptr   指向的   vtbl,然后在   vtbl   中寻找合适的函数指针。这样子会使类所占用的内存增加

 

虚析构函数  
      析构函数也可以是虚的,甚至是纯虚的。例如:  

class   A  

{  

public:  

    virtual   ~A()=0;   //   纯虚析构函数  

};  

 

当一个类打算被用作其它类的基类时,它的析构函数必须是虚的。考虑下面的例子:  

class   A  

{  

public:  

    A()  

    {  

        ptra_   =   new   char[10];

    }  

    ~A()  

    {  

        delete[]   ptra_;

    } //   非虚析构函数  

private:  

    char   *   ptra_;  

};  

 

class   B:   public   A  

 {  

public:  

    B()  

    {  

        ptrb_   =   new   char[20];

    }  

    ~B()  

    {  

        delete[]   ptrb_;

    }  

private:  

    char   *   ptrb_;  

};  

void   foo()  

{  

    A   *   a   =   new   B;  

    delete   a;  

}  

 

在这个例子中,程序也许不会象你想象的那样运行,在执行delete   a的时候,实际上只有A::~A()被调用了,而B类的析构函数并没有被调用!这是否有点儿可怕?如果将上面A::~A()改为virtual,就可以保证B::~B()也在delete   a的时候被调用了。因此基类的析构函数都必须是virtual的。纯虚的析构函数并没有什么作用,是虚的就够了。通常只有在希望将一个类变成抽象类(不能实例化的类),而这个类又没有合适的函数可以被纯虚化的时候,可以使用纯虚的析构函数来达到目的。

构造函数为什么不能为虚函数 & 基类的析构函数为什么要为虚函数

一、构造函数为什么不能为虚函数 1. 从存储空间角度,虚函数对应一个指向vtable虚函数表的指针,这大家都知道,可是这个指向vtable的指针其实是存储在对象的内存空间的。问题出来了,如果构造函数...
  • yusiguyuan
  • yusiguyuan
  • 2014年08月09日 09:37
  • 1062

C++中基类的析构函数为什么要用virtual虚析构函数

C++中基类的析构函数为什么要用virtual虚析构函数, 弄清楚为什么。
  • IIcyZhao
  • IIcyZhao
  • 2013年09月22日 18:41
  • 4623

为什么要用虚函数?什么时候用虚函数?

刚开始学C++学到“类”这一章的时候一直不明白虚函数用来做什么。看书上举的例子不太明白。 #include using namespace std; class Father { public: ...
  • CharlesSimonyi
  • CharlesSimonyi
  • 2013年04月16日 22:25
  • 5572

什么时候要用虚析构函数?

什么时候要用虚析构函数? 通过基类的指针来删除派生类的对象时,基类的析构函数应该是虚的。否则其删除效果将无法实现。 一般情况下,这样的删除只能够删除基类对象,而不能删除子类对象,形成了删除一半形象...
  • rock_joker
  • rock_joker
  • 2017年05月27日 13:20
  • 110

什么时候要用虚析构函数?

什么时候要用虚析构函数?       通过基类的指针来删除派生类的对象时,基类的析构函数应该是虚的。否则其删除效果将无法实现。       一般情况下,这样的删除只能够删除基类对象,而不能删除子类对象...
  • fu_zk
  • fu_zk
  • 2013年08月05日 23:42
  • 966

为什么要用虚析构函数

1 问题引出:为什么要使用虚析构函数?class A //父亲 { public: ~A() { cout ...
  • nwd0729
  • nwd0729
  • 2015年07月15日 17:57
  • 407

虚析构函数示例

  • 2012年02月07日 11:26
  • 472B
  • 下载

虚基类 虚函数成员 虚析构函数

  • 2013年12月26日 23:03
  • 2KB
  • 下载

C++虚基类 虚函数 虚析构函数

  • 2013年12月07日 15:00
  • 725B
  • 下载

C++继承中的虚析构函数

看看下面程序有什么错误: #include using namespace std; class Father { public: Father(){}; ~Father()...
  • yangyangye
  • yangyangye
  • 2015年04月16日 15:42
  • 460
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:为什么要用“虚析构函数”?
举报原因:
原因补充:

(最多只允许输入30个字)