• 深析C++的析构函数-Good Practice: 将基类的析构函数声明为虚函数


    所有C++程序员对析构函数都不陌生,由于其简单且易理解,所以都能很快应用。这里我不说这些常用方法,若不知可参考C++书籍。而我这次所想说的是较微妙的技巧,常不被人注意,但却非常非常的重要。看以下代码:
    //\\////\\////\\////\\////\\////\\//\\////\\////\\//
    //Example 1
    //author: 袁凯
    //date: 2001-09-24
    //\\////\\////\\////\\////\\////\\//\\////\\////\\//

    #include <iostream.h>

    class CFunction
    {
    public:
    CFunction()
    {
    data = new char[64];
    };
    ~CFunction()
    {
    delete [] data;
    };
    char *data;
    };

    class CFunctionEx : public CFunction
    {
    public:
    CFunctionEx()
    {
    m_data = new char[64];
    };
    ~CFunctionEx()
    {
    delete [] m_data;
    };
    private:
    char *m_data;
    };

    void main()
    {
    CFunction *pCFun = new CFunctionEx;
    delete pCFun;
    }
    你能看出什么问题吗?很显然,有内存泄漏。这是因为当删除pCFun时,它只调用了Cfunction的析构函数而没调用CfunctionEx的析构函数,所以导致内存泄漏。再看下例:
    //\\////\\////\\////\\////\\////\\//\\////\\////\\//
    //Example 2
    //author: 袁凯
    //date: 2001-09-24
    //\\////\\////\\////\\////\\////\\//\\////\\////\\//
    #include <iostream.h>
    class CBase
    {
    public:
    CBase()
    {
    data = new char[64];
    };
    ~CBase()
    {
    delete [] data;
    };
    char *data;
    };
    class CFunction
    {
    public:
    CFunction(){};
    ~CFunction(){};
    };
    class CFunctionEx : public CFunction
    {
    public:
    CFunctionEx(){};
    ~CFunctionEx(){};
    private:
    CBase m_cbase;
    };
    void main()
    {
    CFunction *pCFun = new CFunctionEx;
    delete pCFun;
    }
    你能看出什么问题吗?这里CfunctionEx和Cfunction中本身并没有分配内存,应该不会有内存泄漏。和上例一样当删除pCFun 时,它只调用了Cfunction的析构函数而没调用CfunctionEx的析构函数,但CfunctionEx本身并没分配内存,是什么地方有内存泄 漏我不说大家也应该知道了吧。不错是m_cbase,因为它是Cbase的实例且是CfunctionEx成员变量,当CfunctionEx的的析构函 数没有被调用时,当然m_cbase的析构函数也没有被调用,所以Cbase中分配的内存被泄漏。
    解决以上问题的方法很简单,就是使基类Cfunction的析构函数为虚函数就可以了。很简单,是吗?哈哈……
    这样就得出一个结论,当你的基类的析构函数不为虚的话,
    1.1 其子类中所分配的内存将可能泄漏。
    2.2 其子类中所有的成员变量的类中分配的内存也将可能泄漏。
    第二点非常重要,因为很容易被遗漏。我就是为此这才写此文。
    这里说的可能是因为,如果程序中没有以上示例类似写法(指用基类指针指向子类实例裕,虚函数是C++的精华,很少有人不用的,由其是在大中型软件 项目中),就不会出现本文所说的内存泄漏。看来在基类中使析构函数为虚函数是如此的重要。所以强烈建议在基类中把析构函数声明为虚函数,但是只有你写的类 并不做为基类时例外。
    以上我在工作中碰到的问题,程序在VC++6中测试,内存泄漏对于一个高效的服务程序来说十分重要。我想可能大家也可能出现过这种问题,所以写出这篇文章,希望能给大家带来帮助。文章写的仓促,有错别字或错误请大家多包涵。欢迎和大家交流。
  • 相关阅读:
    android修改debug keystore文件使之和正式keystore sha1一致
    scrollView中可以自由滚动的listview
    android gradle的全局管理
    OpenGL学习笔记(三)
    OpenGL学习笔记(二)
    OpenGL学习笔记(一)
    Java编程代码规范中值得留意的地方
    mac上编译Android的arm64位ffmpeg
    入门程序员必读的10本经典书单
    [Android文档翻译]设备兼容性
  • 原文地址:https://www.cnblogs.com/super119/p/2005623.html
Copyright © 2020-2023  润新知