Page's Personal Website

删除父类指针

2022-01-19
c++

[TOC] 最近遇到一个删除父类指针的问题,导致crash,重新学习一下。

问题

  • 1.删除父类指针这个操作是否可行?如何才是可行的?
  • 2.有没有内存泄漏?

学习

  • 测试代码:
      class VA
      {
      public:
          ~VA()
          {
              cout << "~VA()..." << endl;
          }
          virtual void virFunc() = 0;
      };
      class VA1
      {
      public:
          ~VA1()
          {
              cout << "~VA1()..." << endl;
          }
          virtual void virFunc1() = 0;
      };
      class VB : public VA, public VA1
      {
      public:
          ~VB() 
          {
              cout << "~VB()..." << endl;
          }
          virtual void virFunc() override {}
          virtual void virFunc1() override {}
      };
    
      VA* pInst1 = new VB();
      delete pInst1;                    // ok
      VA1* pInst2 = new VB();
      delete pInst2;                    // crash
    

    至于是pInst1还是pInst2那一句宕,得看编译得时候顺序

  • 问题1可行,但是父类需要有虚析构函数 参考[4][5],说删除一个指向子类的父类指针,行为未定义
    if the static type of the object to be deleted is different from its dynamic type, the static type shall be a base class of the dynamic type of the object to be deleted and the static type shall have a virtual destructor or the behavior is undefined.
    
  • 问题2,存在内存泄漏的可能,毕竟是行为未定义 参考[1]

问题1解决方法

  • 方法一:删除子类指针 这个好说,就是代码看起来有点不太舒服
    VB* pVB = dynamic_cast<VB*>(pInst2);
    delete pVB;
    
  • 方法二:父类都设置虚析构函数
    virtual ~VA()
    virtual ~VA1()
    
  • 对于抽象类要没事虚析构函数,要么是protected的析构函数 参考[8] ``` Every abstract class should either have a,

protected destructor, or, virtual destructor. ```

参考

[1]类继承中,通过基类指针delete释放,是否会造成内存泄漏 [2]C++多重继承带来的指针转换问题 [3]Cpp 对象模型探索 / 多重继承下基类指针释放子类对象的原理说明 [4]when-to-use-virtual-destructors [5]《Effective C++》 [6]expr.delete [7]virtual destructor for pure abstract class [8]Should every class have a virtual destructor?


Comments

Content