zoukankan      html  css  js  c++  java
  • C++ 虚析构函数

    为什么基类需要虚析构函数?下面给出一个例子

    #include <iostream>
    using namespace std;
    class A{
        public:
        ~A(){ cout << "~A()" << endl; }
        //virtual ~A(){ cout << "~A()" << endl; }
    };
    
    class B : public A{
        ~B(){ cout << "~B()" << endl; }
    };
    
    int main()
    {
        A* p = new B;
        delete p;
    }

    编译:g++ -Wall ./v-deconstr.cpp

    执行:~A()

    会发现,析构函数只调用了基类的析构函数,派生类没有被析构。原因个人理解就是由于p是指向A的指针,会有up casting,导致delete p时,调用A的析构函数。

    #include <iostream>
    using namespace std;
    class A{
        public:
        //~A(){ cout << "~A()" << endl; }
        virtual ~A(){ cout << "~A()" << endl; }
    };
    
    class B : public A{
        ~B(){ cout << "~B()" << endl; }
    };
    
    int main()
    {
        A* p = new B;
        delete p;
    }

    Class A的析构函数改为虚函数,在编译执行结果为:

    ~A()
    ~B()

    这样析构才是正确的,把派生类和基类的析构函数都调用,释放正确。

    如果是

    B *pB = new B;
    delete pB;

    输出则是
    ~B()
    ~A()

    原因分析:

    pB是静态的,析构的时候,因此会依次调用~B,~A。
    但p是A类型的,在使用delete时如果A的析构函数不是虚函数,则会只调用A的析构函数,造成子类的内存泄露;
    而如果A的析构函数是虚函数,由于存在动态绑定,并且通过指针或者引用,存在派生类向基类转换则,delete会在调用完~A,发现~A是虚函数,再调用~B,完成全部的析构。

     

  • 相关阅读:
    stl
    Chopsticks Hdu1500
    Dp Hdu1421 搬寝室
    AOj448有趣的矩阵
    树状数组Hdu1541
    树状数组Hdu1166
    Floyd最小环Hdu1599
    三大主流ETL工具选型
    ETL概述
    POI操作Excel常用方法总结
  • 原文地址:https://www.cnblogs.com/tingjie-word/p/7843023.html
Copyright © 2011-2022 走看看