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

    我知道,对于存在虚函数的基类,一般需要将基类的析构函数定义为虚函数,从而实现资源的合理释放,而且我也知道派生类在重载时,只需要清理自己的对象,不过,有时候还是会有些疑惑感,所以写了一个简单的例子,来消除疑惑。下面是实例内容:

    #include <iostream>
    
    class student
    {
    public:
        student() {}
        ~student() { std::cout << "a student" << std::endl; }
    };
    
    class bachelor
    {
    public:
        bachelor() {}
        ~bachelor() { std::cout << "a bachelor" << std::endl; }
    };
    
    class studentHolder
    {
    public:
        studentHolder()
        {
    
        }
    
        virtual ~studentHolder() {}
    
    
    private:
        student st;
    };
    
    class bachelorHolder : public studentHolder
    {
    public:
        bachelorHolder()
            : studentHolder()
        {
    
        }
    
        ~bachelorHolder() override
        {
    
        }
    
    private:
        bachelor bcl;
    };

    下面是调用的地方的代码:

    #define _CRTDBG_MAP_ALLOC
    #include <stdlib.h>
    #include <crtdbg.h>
    
    int main()
    {
        _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
        studentHolder* holder = new bachelorHolder();
        delete holder;
        return 0;
    }

    这种情况下,会执行正确的清理操作:

    这种情况下,如果将bachelorHolder中的析构函数删除,即:

    class bachelorHolder : public studentHolder
    {
    public:
        bachelorHolder()
            : studentHolder()
        {
    
        }
    
    private:
        bachelor bcl;
    };

    这种情况下,对象依然被很好的清理,因为C++会默认为类创建一个析构函数,而且如果基类为虚函数,派生类创建的为重写基类的虚函数。结果依然是:

    如果在上述的情况下,将studentHolder析构函数的virtual移除,即:

    class studentHolder
    {
    public:
        studentHolder()
        {
    
        }
    
        ~studentHolder() {}
    
    
    private:
        student st;
    };

    结果将变成:

    不过,注意一点,这里,只是说派生类的析构函数没有被调用,资源(分配的堆内存)还是会被很好的释放。这里,可以查看,如果我们将main函数中的delete holder;注释掉:

    int main()
    {
        _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
        studentHolder* holder = new bachelorHolder();
        // delete holder;
        return 0;
    }

    在debug模式下,进行调试,会在output窗口,得到如下结果:

    而就算将main函数,改为如下:

    int main()
    {
        _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
        studentHolder* holder = new bachelorHolder();
        delete reinterpret_cast<void*>(holder);
        return 0;
    }

    在output窗口,都不会出现内存泄漏的显示。大致内容就是上述显示,在有疑虑的时候,可以参考一下。

  • 相关阅读:
    年近30,朋友聚会都聊什么?
    2016世界最热门的编程语言与薪资揭秘
    程序员的春天来了,最美赏花旅游地十大攻略
    雄联盟工程师独家分享:如何使开发更有效率
    小偷被抓叫嚣:我不偷警察没饭吃
    3.7女生节:被程序员男友送的奇葩礼物宠哭了
    最适合程序员加班吃的6大营养美食
    谷歌汽车出误判曝光 6大奇葩科技更牛
    【程序员的爱情】彼岸花开谁又种下了执念
    分享10个免费或便宜的Photoshop替代工具
  • 原文地址:https://www.cnblogs.com/albizzia/p/8979078.html
Copyright © 2011-2022 走看看