• 关于虚析构函数的问题


    关注 码龄 粉丝数 原力等级 -- 被采纳 被点赞 采纳率 杨佳音731 2024-04-25 21:25 采纳率: 92.1% 浏览 0 首页/ 编程语言 / 已采纳 关于虚析构函数的问题 c++c语言 设置了虚析构函数,那么Base *b=new Derived(),不太明白为什么,明明是基类的指针,但是动态开辟空间的时候却使用派生类的名称。为什么他加了那个虚构造函数之后就能析构派生类 展开全部 收起 写回答 好问题 0 提建议 追加酬金 关注问题 微信扫一扫 点击复制链接 分享 邀请回答 编辑 收藏 删除 结题 收藏 举报 追加酬金 (90%的用户在追加酬金后获得了解决方案) 当前问题酬金 ¥ 0 (可追加 ¥500) ¥ 15¥ 20¥ 50¥ 100¥ 200 支付方式 扫码支付 二维码出错 点击刷新 支付金额 15 元 提供问题酬金的用户不参与问题酬金结算和分配 支付即为同意 《付费问题酬金结算规则》 结题 再想想 删除 再等等

    1条回答 默认 最新

    • 码农阿豪 Java领域优质创作者 2024-04-25 21:39
      关注
      让阿豪来帮你解答,本回答参考chatgpt3.5编写提供,如果还有疑问可以评论或留言
      问题解答: 在派生类中如果没有显式地定义析构函数,那么会默认调用基类的析构函数。但是如果派生类中有动态分配的资源,如果不手动释放的话,就会导致内存泄漏。所以为了解决这个问题,C++中引入了虚析构函数的概念。 虚析构函数就是可以实现基类指针可以指向派生类对象,并通过基类指针释放动态分配的内存空间。在基类中定义虚析构函数,通过多态性让派生类释放空间时首先调用析构函数,再释放空间。 所以,在 Base *b=new Derived() 的情况下,使用了派生类的名称,是因为通过继承,派生类拥有了基类中的成员变量和成员函数。而在这个例子中,如果派生类中有动态分配的资源需要手动释放,那么需要用到析构函数,因此定义虚析构函数让基类指针可以指向派生类对象,并通过基类指针释放动态分配的内存空间。 举个例子,假设有一个基类`Animal`和一个派生类`Cat`,其中`Cat`定义了动态分配的资源。如果没有虚析构函数,那么在释放`Cat`对象时会出现内存泄漏。代码如下:
      class Animal {
      public:
          virtual void move() {
              cout << "Animal move" << endl;
          }
      };
      class Cat : public Animal {
      public:
          Cat() {
              p = new int(10);
          }
          void move() {
              cout << "Cat move" << endl;
          }
          ~Cat() {
              cout << "Cat destructor" << endl;
              delete p;
          }
      private:
          int *p;
      };
      int main() {
          // 使用普通指针释放空间
          Animal *a = new Cat();
          delete a;  // 只会调用基类的析构函数,导致Cat的析构函数没有被调用,从而产生内存泄漏
          return 0;
      }
      

      而如果定义虚析构函数,就可以避免这个问题,代码如下:

      class Animal {
      public:
          virtual void move() {
              cout << "Animal move" << endl;
          }
          virtual ~Animal() {
              cout << "Animal destructor" << endl;
          }
      };
      class Cat : public Animal {
      public:
          Cat() {
              p = new int(10);
          }
          void move() {
              cout << "Cat move" << endl;
          }
          ~Cat() {
              cout << "Cat destructor" << endl;
              delete p;
          }
      private:
          int *p;
      };
      int main() {
          // 使用基类指针释放空间,保证调用派生类的析构函数
          Animal *a = new Cat();
          delete a;
          return 0;
      }
      

      输出结果:

      Cat destructor
      Animal destructor
      

      展开全部

      本回答被题主选为最佳回答 , 对您是否有帮助呢?
      评论
    编辑
    预览

    报告相同问题?

  • 相关阅读:
    elementui中table进行表单验证
    【自用笔记】nginx 配置多 context 及简单负载均衡
    我为什么不喜欢关电脑?
    基于SSM和VUE的留守儿童信息管理系统
    运筹说 第79期|论文速读之双目标岛屿旅行商问题
    Android 开机动画的启动过程BootAnimation(基于Android10.0.0-r41)
    航天科技×辰安科技 打造智慧化工园区安全保障平台
    adobe pdf 合并文件后提示“无法提取嵌入的字体”问题解决方法
    2022 PAT 甲级(秋季)
    【Python】第一课 Python环境搭建
  • 原文地址:https://ask.csdn.net/questions/8094999