zoukankan      html  css  js  c++  java
  • C++基类的析构函数定义为虚函数的原因

    1:每个析构函数只会清理自己的成员(成员函数前没有virtual)。
    2:可能是基类的指针指向派生类的对象,当析构一个指向派生类的成员的基类指针,这时程序不知道这么办,可能会造成内存的泄露,因此此时基类的析构函数要定义为虚函数;
    基类指针可以指向派生类的对象(多态),如果删除该指针delete[]p,就会调用该指针指向的派生类的析构函数,而派生类的对象又会自动调基类的成员函数,这样就会把派生类的对象释放,如果基类的析构函数没有定义成虚函数,则编译器实现的静态绑定,在删除基类的指针,只会释放基类的析构函数而不会释放派生类的成员函数,此时会导致释放内存不完全,就会导致内存泄露的问题。
    一:派生类指针指向派生类的对象

    class Base
    {
    public: Base()
    { cout << "Base()" << endl; }

    virtual ~Base()
    {
    cout << "~Base()" << endl;
    }
    };
    class Driver :public Base
    {
    public: Driver()
    {
    cout << "Driver()" << endl;
    }
    ~Driver()
    {
    cout << "~Driver()" << endl;
    }
    };
    void Test()
    {
    Driver*pd = new Driver;
    delete pd;
    }

    结果:

    base()

    Driver()

    ~Driver()

    ~Base()

    派生的指针指向派生类的对象,释放p的过称是先释放派生类的析构函数,再释放基类的析构函数
    二:基类的指针指向派生类的对象(无virtual)

    class Base 
    {

    public: Base()
    {
    cout << "Base()" << endl;
    }
    ~Base()
    {
    cout << "~Base()" << endl;
    }
    };

    class Driver :public Base
    {

    public: Driver()
    {
    cout << "Driver()" << endl;
    }
    ~Driver()
    {
    cout << "~Driver()" << endl;
    }
    };
    void Test()
    {
    Base *pd = new Driver;
    delete pd;
    }

    运行结果:

    Base()

    Driver()

    ~Basce()

    当基类的指针指向派生类的对象的成员,释放pd的过程是:只是释放了基类的资源,而没有调用派生类的析构函数;这样的删除只能删除基类对象,而不能删除派生类的对象,造成内存泄露;
    在公有继承中,基类对派生类的对象的操作,只能影响哪些继承的成员,如果想要基类对非继承进行操作,则要把这个基类函数定义为虚函数;

  • 相关阅读:
    学习使用linux下tags文件
    uboot常用命令详解
    U-boot中TFTP 解释
    eth0: ERROR while getting interface flags: No such device 没有eth0 有其他的eth
    取消挂载 umount 时出现的 “Device is busy”
    Linux的log日志功能
    oracle的安装
    SOA架构设计分析
    立方体模型
    质量属性的六个常见属性场景(淘宝网)
  • 原文地址:https://www.cnblogs.com/wanghuixi/p/10400185.html
Copyright © 2011-2022 走看看