zoukankan      html  css  js  c++  java
  • 析构函数为什么要定义成虚函数

    结论:

      实现多态时,我们通过基类指针指向子类对象,在delete基类指针时,我们希望先调用子类的析构函数,再调用父类的析构函数,要实现这个目的,析构函数就必须定义成虚函数,否则只会调用父类的析构函数,子类的析构函数不会被调用。

    实验1:析构函数不定义成虚函数

    #include <iostream>
    
    using namespace std;
    
    class father {
    public:
        father(int num) {
            cout << "create father" << endl;
            // new申请的内存不用判空,new不到内存会抛出异常,不会返回空指针
            father_ptr = new int(num);
        }
    
        ~father() {
            cout << "destory father" << endl;
            if (father_ptr != nullptr) {
                delete father_ptr;
            }
            // 释放内存以后,一定记得置空,防止出现野指针
            father_ptr = nullptr;
        }
    
    private:
        int *father_ptr;
    };
    
    class child : public father {
    public:
        // 父类没有无参构造函数,需要显示调用父类构造函数
        child(int x, int y) : father(x) {
            cout << "create child" << endl;
            child_ptr = new int(y);
        }
    
        ~child() {
            cout << "destory child" << endl;
            if (child_ptr != nullptr) {
                delete child_ptr;
            }
            child_ptr = nullptr;
        }
    
    private:
        int *child_ptr;
    };
    
    int main()
    {
        father *ptr = new child(10, 20);
        delete(ptr);
        return 0;
    }

    运行结果:结果说明不定义成虚函数,只会调用父类的析构函数,不会调用子类的析构函数,导致内存泄露。

    实验2:析构函数定义成虚函数

    #include <iostream>
    
    using namespace std;
    
    class father {
    public:
        father(int num) {
            cout << "create father" << endl;
            // new申请的内存不用判空,new不到内存会抛出异常,不会返回空指针
            father_ptr = new int(num);
        }
    
        virtual ~father() {
            cout << "destory father" << endl;
            if (father_ptr != nullptr) {
                delete father_ptr;
            }
            // 释放内存以后,一定记得置空,防止出现野指针
            father_ptr = nullptr;
        }
    
    private:
        int *father_ptr;
    };
    
    class child : public father {
    public:
        // 父类没有无参构造函数,需要显示调用父类构造函数
        child(int x, int y) : father(x) {
            cout << "create child" << endl;
            child_ptr = new int(y);
        }
    
        virtual ~child() {
            cout << "destory child" << endl;
            if (child_ptr != nullptr) {
                delete child_ptr;
            }
            child_ptr = nullptr;
        }
    
    private:
        int *child_ptr;
    };
    
    int main()
    {
        father *ptr = new child(10, 20);
        delete(ptr);
        return 0;
    }

    运行结果:父类和子类都正常析构了。

    tips:良好的编程习惯,不管类中有没有指针,有没有动态申请内存,都应该把析构函数定义成虚函数,定义成虚函数总是不会错的。

    https://i.cnblogs.com/posts?categoryid=0
  • 相关阅读:
    JSON
    类的操作
    轮播图
    定时器的应用
    延时调用
    定时器
    跳表的java实现,转载自网络,仅供自己学习使用
    java实现判断两个二叉树是否相同
    开发小白工作过程中的一些经验记录,仅供自己参看查阅,转载请注明出处
    安卓基础入门二,转载自网络
  • 原文地址:https://www.cnblogs.com/418ks/p/14706243.html
Copyright © 2011-2022 走看看