zoukankan      html  css  js  c++  java
  • 虚析构和纯虚析构

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

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

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

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

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

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

    虚析构语法:

    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");
    }

  • 相关阅读:
    如何只通过Sandboxed Solution启动一个定时执行的操作
    创建与SharePoint 2010风格一致的下拉菜单 (续) 整合Feature Custom Action框架
    创建与SharePoint 2010风格一致的下拉菜单
    《SharePoint 2010 应用程序开发指南》第二章预览
    SharePoint 2013 App 开发 (1) 什么是SharePoint App?
    使用Jscex增强SharePoint 2010 JavaScript Client Object Model (JSOM)
    搜索范围的管理
    SharePoint 2010 服务应用程序(Service Application)架构(1)
    SharePoint 2010 服务应用程序(Service Application)架构(2)
    SharePoint 2013 App 开发 (2) 建立开发环境
  • 原文地址:https://www.cnblogs.com/roscangjie/p/11419448.html
Copyright © 2011-2022 走看看