zoukankan      html  css  js  c++  java
  • 虚析构、纯虚析构

    析构函数的工作方式是:最底层的派生类(most derived class)的析构函数最先被调用,然后调用每一个基类的析构函数。--从高到低依次析构…

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

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

    例如:

    class A
    {
    public:
       ~A()                // 非虚析构
       {
          cout < <"A::~A" < <endl;
       }
    };

    class B:public A
    {
    public:
       virtual ~B()    // 虚析构
       {
          cout < <"B::~B" < <endl;
       }
    };

    class C:public B
    {
    public:
       ~C()
       {
          cout < <"C::~C" < <endl;
       }
    };
    int main()
    {
       A *a=new A();
       B *b=new B();
       C *c=new C();
       A *d=new B();     // 指向派生类的基类指针
       A *e=new C();     // 指向派生类的派生类的基类指针
       B *f=new C();      // 指向派生类的派生类指针
       delete a;
       cout < <endl;
       delete b;
       cout < <endl;
       delete c;
       cout < <endl;
       delete d;
       cout < <endl;
       delete e;
       cout < <endl;
       delete f;
       cout < <endl;
       system("Pause");
    }

    所以:

    1. 如果一个类要被另外一个类继承,而且用其指针指向其子类对象时,那么父类的析构必须是虚的,否则在delete该对象指针时,子类的析构函数将不会被调用。

    2. 另外要记住,在构造一个类的对象时,先构造其基类子对象,即调用其基类的构造函数,然后调用本类的构造函数,这和析构是相反的。

    3. 只要最底层基类的析构是虚的,那么子类的析构无论是否显视的写成虚或不虚,其实都是虚的。

  • 相关阅读:
    EOF ---shell编程
    Linux错误代码含义
    linux连接sybase数据库-isql
    CH7-WEB开发(集成在一起)
    [转]ASP.NET MVC 入门10、Action Filter 与 内置的Filter实现(实例-防盗链)
    [转]ASP.NET MVC 入门9、Action Filter 与 内置的Filter实现(介绍)
    [转]ASP.NET MVC 入门8、ModelState与数据验证
    [转]ASP.NET MVC 入门7、Hellper与数据的提交与绑定
    [转]ASP.NET MVC 入门6、TempData
    [转]ASP.NET MVC 入门5、View与ViewData
  • 原文地址:https://www.cnblogs.com/davidsguo008/p/3604681.html
Copyright © 2011-2022 走看看