zoukankan      html  css  js  c++  java
  • C++析构函数的自动调用(析构函数必须是虚拟的,这样删除父类指针指向的子类对象,才能同时调用两者的析构函数,否则就没有机会调用子类析构函数)

    class A {
    public:
    A() { printf("A "); }
    ~A() { printf(" ~A "); } // 这里不管写不写virtual,删除B对象的时候,都会被执行。因为这个例子是B*指针指向B对象,不是A*指针指向B对象。
    };

    class B : public A
    {
    public:
    B() { printf("B "); }
    ~B() { printf("~B "); }
    };

    int main(int argc, char* argv[])
    {
    B* b = new B;

    delete b;
    return 0;
    }
    int main(int argc, char* argv[])
    {
    B b; // 虽然正确,但其实是非正常情况,因为你防不住程序员定义A* a = new B(); 这样就错了。
    return 0;
    }
    执行结果:
    A
    B
    ~B
    ~A

    结论:删除子类指针,无论如何会自动调用祖先类的析构函数(即使祖先类的习惯函数不是虚拟的),虽然这是非正常情况,但还是记一下。

    ------------------------------------------------------------

    class A {
    public:
    A() { printf("A "); }
    virtual ~A() { printf(" ~A "); } // 增加了虚拟关键字
    };

    class B : public A
    {
    public:
    B() { printf("B "); }
    ~B() { printf("~B "); }
    };

    int main(int argc, char* argv[])
    {
    A* a = new B;

    delete a;
    return 0;
    }
    执行结果(正常情况,子类祖先类的析构函数都是虚拟的,这样删除祖先类指针、子类对象的时候,可正确同时调用子类和祖先类的析构函数):
    A
    B
    ~B
    ~A
    但是如果去掉 virtual(这里是A*指针指向B对象),改一下立刻有效果,变成了错误(错误情况)。
    执行结果:
    A
    B
    ~A

    总结:自己类型的指针指向自己的对象,怎么样都没有问题(不管父类析构函数写不写virtual)。只有基类指针指向子类对象的时候,一定需要virtual关键字的配合,才能正确的工作。

  • 相关阅读:
    linux(CENTOS)系统各个目录的作用详解
    2018 焦作E java 高精度暴力
    [SHOI2015]激光发生器,计算几何 直线相交
    codeforces 600E dfs+线段树合并
    2018 南京区域赛A SG打表
    8个常见的硬币博弈的SG值规律
    hdu 3389 阶梯博弈
    组合游戏与博弈好文
    gym 100500B 多项式哈希+Rabbin-Karp/最小表示法
    zjoi 2007 捉迷藏 动态点分治+可删堆
  • 原文地址:https://www.cnblogs.com/findumars/p/3357626.html
Copyright © 2011-2022 走看看