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
  • 相关阅读:
    为图片指定区域添加链接
    数值取值范围问题
    【leetcode】柱状图中最大的矩形(第二遍)
    【leetcode 33】搜索旋转排序数组(第二遍)
    【Educational Codeforces Round 81 (Rated for Div. 2) C】Obtain The String
    【Educational Codeforces Round 81 (Rated for Div. 2) B】Infinite Prefixes
    【Educational Codeforces Round 81 (Rated for Div. 2) A】Display The Number
    【Codeforces 716B】Complete the Word
    一个简陋的留言板
    HTML,CSS,JavaScript,AJAX,JSP,Servlet,JDBC,Structs,Spring,Hibernate,Xml等概念
  • 原文地址:https://www.cnblogs.com/418ks/p/14706243.html
Copyright © 2011-2022 走看看