• C++ 虚析构函数


    Virtual 关键字起到什么作用

    借鉴网友blog, 了解了虚析构函数的作用:

      虚析构函数是为了避免内存泄露,而且是当子类中会有指针成员变量时才会使用得到的。

      也就说虚析构函数使得在删除指向子类对象的基类指针时可以调用子类的析构函数达到释放子类中堆内存的目的,而防止内存泄露的。

     c++中的函数调用默认不适用动态绑定,要触发动态绑定,必须满足两个条件:第一指定为虚函数; 第二通过基类类型的引用或指针调用 

    Virtual继承及示例和注意事项 --》 注意, 加了virtual的虚虚构函数和不加virtual的析构函数结果不一样哦

    virtual可用来定义类函数和应用到虚继承中

    注意:

      有元函数、构造函数、static静态函数不能用virtual关键字修饰。普通成员函数和析构函数可以用virtual关键字修饰。

      

    #include<stdlib.h>
    #include<iostream>
    
    using namespace std;
    
    class GrandFather {
    public:
        GrandFather() {}
    
        virtual void fun() {
            cout << "GrandFather call function" << endl;
        }
    };
    
    class Father : public GrandFather {
    public:
        Father() {}
    
        void fun() {
            cout << "Father call function" << endl;
        }
    };
    
    class Son : public Father {
    public:
        Son() {}
    
        void fun() {
            cout << "Son call function" << endl;
        }
    };
    
    void Print(GrandFather *father) {
        father->fun();
    }
    
    int main(int argc, char const *argv[]) {
        Father *pfather = new Son;
        pfather->fun();
        delete pfather;
    
    //    GrandFather *grandfather = new Father;
    //    Print(grandfather);
    
        return 0;
    }
    带有自定义virtual的类自定义虚函数

    多继承的带virtual的虚析构函数

    #include <iostream>
    
    using namespace std;
    
    class GraphFather {
    private:
    
    public:
        GraphFather(){
            cout << "GraphFather structure" << '
    ';
        };
        virtual ~GraphFather(){
            cout << "GraphFather deconstruction" << '
    ';
        };
    };
    
    
    class Father : public GraphFather {
    private:
    
    public:
        Father(){
            cout << "Father structure" << "
    ";
        };
        ~Father(){
            cout << "Father deconstruction" << "
    ";
        };
    };
    
    
    class Son: public Father {
    private:
    
    public:
        Son(){
            cout << "Son structure" << "
    ";
        };
        ~Son(){
            cout << "Son Deconstruction" << "
    ";
        };
    };
    
    
    int main(int argc, char const *argv[]){
        Father *gfather = new Son;
        delete gfather;
    
    
        return 0;
    };
    带virtual的虚析构函数

    返回值:

    Son call function

    先看第一个例子:

      

    #include <iostream>
    
    using namespace std;
    
    class GraphFather {
    private:
    
    public:
        GraphFather(){
            cout << "GraphFather structure" << '
    ';
        };
        ~GraphFather(){
            cout << "GraphFather deconstruction" << '
    ';
        };
    };
    
    
    class Father : public GraphFather {
    private:
    
    public:
        Father(){
            cout << "Father structure" << "
    ";
        };
        ~Father(){
            cout << "Father deconstruction" << "
    ";
        };
    };
    
    
    class Son: public Father {
    private:
    
    public:
        Son(){
            cout << "Son structure" << "
    ";
        };
        ~Son(){
            cout << "Son Deconstruction" << "
    ";
        };
    };
    
    
    int main(int argc, char const *argv[]){
        GraphFather *gfather = new Son;
        delete gfather;
        cout << "================" << '
    ';
        Father *father = new Son;
        delete father;
        cout << "================" << '
    ';
        Son *son = new Son;
        delete son;
        cout << "================" << '
    ';
    
        return 0;
    };

    返回值:

      

    GraphFather structure
    Father structure
    Son structure
    GraphFather deconstruction  -----》 看这里
    ================
    GraphFather structure
    Father structure
    Son structure
    Father deconstruction  ------看这里
    GraphFather deconstruction
    ================
    GraphFather structure
    Father structure
    Son structure
    Son Deconstruction  -------看这里
    Father deconstruction
    GraphFather deconstruction
    ================

    这样只是理解了执行顺序, 但网友的那篇blog却讲的很好, 记录只是为了更好的理解和回顾

    更好的理解virtual的作用, 和使用场景

    #include <iostream>
    
    using namespace std;
    
    class Base
    {
    public:
        Base(){}
        ~Base()
        {
            cout << "Base Destructor." << endl;
        }
    private:
        int a, b;
    };
    
    class Derive : public Base
    {
    public:
        Derive(){}
        ~Derive()
        {
            cout << "Derive Destructor." << endl;
            // release memeory
            if(pI != NULL)
            {
                delete pI;
            }
        }
    private:
        int *pI;
    };
    
    int main(void)
    {
        {
            Base *pD = new Derive;
            delete pD;
        }
        int i;
        cin >> i;
    
        return 0;
    }
    View Code

    但结果只执行了基类的析构函数, 在派生类中有没有释放的指针, 这样就造成了内存泄漏

    这也是虚析构函数的一个作用

    在基类Base中加入虚析构函数virtual ~Base()...

    #include <iostream>
    
    using namespace std;
    
    class Base {
    public:
        Base() {}
    
        virtual ~Base() {
            cout << "Base Destructor." << endl;
        }
    
    private:
        int a, b;
    };
    
    class Derive : public Base {
    public:
        Derive() {
            pI = new int;
        }
    
        ~Derive() {
            cout << "Derive Destructor." << endl;
            // release memeory
            if (pI != NULL) {
                delete pI;
            }
        }
    
    private:
        int *pI;
    };
    
    int main(int argc, char const *argv[]) {
        {
            Base *pD = new Derive;
            delete pD;
        }
        int i;
        cin >> i;
    
        return 0;
    }

    参考blog1:https://www.cnblogs.com/lit10050528/p/3874703.html

    参考blog2: http://www.cnblogs.com/cxq0017/p/6550125.html   --》这个blog代码没有delete 对象指针, 需注意

  • 相关阅读:
    Redis:特殊数据类型,hyperloglog(基数),bitmap(位存储)
    Redis:特殊类型geospatial(地理位置类型,纬经度)
    Redis:zset常用指令
    Redis:hash常用指令
    Redis:set集合常用常用指令
    Pytorch学习-数据操作
    天池Python训练营笔记—Python基础入门:从变量到异常处理
    Python基础语法快速复习-面对对象编程
    Python基础语法快速复习-函数式编程
    Python基础语法快速复习-高级特性
  • 原文地址:https://www.cnblogs.com/renfanzi/p/9334897.html
Copyright © 2020-2023  润新知