• 虚析构和纯虚析构


    多态使用时,如果子类有对象开辟到堆区,那么父类指针在释放时无法调用到子类的析构代码

    解决方式:将父类中的析构函数改为虚析构或者春虚析构

    虚析构和纯虚析构的共性:

    • 可以解决父类指针释放子类对象
    • 都需要有具体的函数实现

    虚析构和纯虚析构的区别:

    • 如果是纯虚析构,该类属于抽象类,无法实例化对象

    虚析构语法:

    virtual ~类名(){}

    纯虚析构语法:

    virtual ~类名()=0;
    类名::类名(){};

     常规操作:

    #include<iostream>
    using namespace std;
    class animal
    {
    public:
        virtual void speak() = 0;
    };
    
    
    class dog : public animal
    {
    public:
        void speak()
        {
            cout << "小狗在说话" << endl;
        }
    };
    
    
    class cat : public animal
    {
    public:
        void speak()
        {
            cout << "小猫在说话" << endl;
        }
    };
    void test01()
    {
        animal* it = new cat;
        it->speak();
        delete it;
    }
    int main()
    {
        test01();
        system("pause");
    }

    但是如果子类对象有开辟空间到堆区时,在子类中创建指针:

    class cat : public animal
    {
    public:
        void speak()
        {
            cout << *m_name<<"小猫在说话" << endl;
        }
        cat(string name) {
            m_name =new string(name);
        }
        string* m_name;
    };
    void test01()
    {
        animal* it = new cat("tom");
        it->speak();
        delete it;
    }

    在父类子类对象中都打印一些字符会发现,子类的析构函数并没有调用,说明堆区并没有释放干净,这样就会造成内存泄露。

    这是因为父类指针在析构时并不会调用子类的析构函数,导致子类如果有堆区对象,就会造成内存泄露。

    cat类中有堆区属性,应该在该子类中将其释放,解决这个问就就需要虚析构

    虚析构的语法就是在父类析构函数前加上一个virtual关键字,结果:

    子类的析构函数已调用。

     以上就是利用父类指针解决子类对象时释放不干净的问题

    纯虚析构

    纯虚析构需要有什声明,也需要有具体 的实现;

    有了纯虚析构后这个类也属于抽象类,无法实例化对象;

    #include<iostream>
    #include<string>
    using namespace std;
    class animal
    {
    public:
        animal()
        {
            cout << "animal构造函数已调用" << endl;
        }
        //virtual ~animal()  //虚析构    虚析构与纯虚析构只能存在一个
        //{
        //    cout << "animal析造函数已调用" << endl;
        //}
        virtual ~animal() = 0; //纯虚析构声明
        virtual void speak() = 0;
    };
    animal::~animal() //纯虚析构具体实现
    {
        cout << "animal纯虚析构已调用" << endl;
    };
    
    class dog : public animal
    {
    public:
        void speak()
        {
            cout << "小狗在说话" << endl;
        }
    };
    
    
    class cat : public animal
    {
    public:
        void speak()
        {
            cout << *m_name<<"小猫在说话" << endl;
        }
        cat(string name) {
            cout << "cat构造函数已调用" << endl;
            m_name =new string(name);
        }
        ~cat()
        {
            if (m_name != NULL)
            {
                cout << "cat析构函数已调用" << endl;
                delete m_name;
                m_name = NULL;
            }
        }
    
        string* m_name;
    };
    void test01()
    {
        animal* it = new cat("tom");
        it->speak();
        delete it;
    }
    int main()
    {
        test01();
        system("pause");
    }

  • 相关阅读:
    linux上运行jmeter-server失败
    转:JMeter整合InfluxDB,Grafana让测试结果实时显示
    转:基于InfluxDB&Grafana的JMeter实时性能测试数据的监控和展示
    转:Linux下用Jmeter做接口测试
    关于获取IP 电脑获取准确手机获取的IP不准确
    关于MVC微信开发遇到的那些坑。
    uploadify 上传 大文件没有反映
    HTTP 错误 404.3
    关于WEBAPI 的使用 和WEBAPI CORS 的使用过程遇到的问题
    MVC4 ViewModel 存入多个Model,以及前台的显示用法。具体类名可以参数代替
  • 原文地址:https://www.cnblogs.com/roscangjie/p/11419448.html
Copyright © 2020-2023  润新知