1

前任:

class base
{
public:
  base()
  {
    // allocate memory for basearray
  }
  virtual ~base()
  {
    // delete basearray
  }

protected:
  float* basearray;
};

class derived1 : public base
{
public:
  derived1()
  {
    // allocate memory for derivedarray
  }
  ~derived1()
  {
    // delete derived array
  }

protect:
  float* derivedarray;
};

void main()
{
  derived1 d;

  ...

  base* pb = &d;

  ...

  // Delete base array? 
}

我的基类中有一个虚拟析构函数和一个数组。如果基类析构函数被派生类析构函数覆盖,则基数组不会被删除。什么是好的解决方案?

4

5 回答 5

9

在派生类析构函数运行后,会自动调用基类析构函数

于 2012-01-30T19:31:42.777 回答
2

当析构派生对象并且基的析构函数是虚拟的时,两个析构函数都会被调用。你可以在这里确认:http: //ideone.com/RZamr

该顺序将与构造函数的顺序相反,即在构造时首先base调用构造函数 of ,然后调用 on of derived。当首先破坏时,derived将调用 的析构函数,然后调用 的base

于 2012-01-30T19:34:56.450 回答
1

虚拟析构函数的工作方式与其他虚拟函数的工作方式不同,因为基类的虚拟析构函数永远不会被覆盖。相反,当子类提供自己的析构函数时,该子类析构函数会触发,然后基类析构函数也会触发。这里使用“虚拟”是为了如果通过基类指针删除派生类对象,C++ 知道根据对象的动态类型(子类)而不是指针的静态类型(超类)。因此,您不需要在这里做任何特别的事情。基类析构函数将照常工作。

希望这可以帮助!

于 2012-01-30T19:35:28.293 回答
0

当覆盖析构函数时,基类析构函数仍然被调用,只要它被定义为“虚拟”,这就是你所做的。

所以在这个例子中:

  class base
  {
  public:
     base()
     {
        myarray = new float[100];
     }

     ~base()
     {
        delete[] myarray;
     }

  private:
     float* myarray;
  }


  class derived : public base
  {
  public:
     derived()
     {
     }

     ~derived()
     {
     }
  }

这不会删除“myarray”并且会泄漏内存,因为基类析构函数被派生类析构函数隐藏。然而:

  class base
  {
  public:
     base()
     {
        myarray = new float[100];
     }

     virtual ~base()
     {
        delete[] myarray;
     }

  private:
     float* myarray;
  }


  class derived : public base
  {
  public:
     derived()
     {
     }

     ~derived()
     {
     }
  }

这将删除数组。

请记住,构造函数是从基类向上调用的,因此首先调用基类构造函数,然后调用派生类,而调用析构函数的顺序相反,因此您的派生类析构函数在基类之前调用.

于 2012-01-30T19:40:24.047 回答
0

这里没有问题。在调用派生类析构函数之后立即调用基类析构函数。

只有一种情况是不正确的:在指向基类析构函数不是虚拟的基类的指针上调用 delete。

在所有情况下,如果你有一个类的本地实例,在堆栈上创建,并且函数或方法退出,即使是因为异常,实例也会被正确地破坏。

new在类的实例为d 并且随后通过指向被实例化的确切类的指针删除的所有情况下,该实例被正确地破坏。

当一个类的实例是newd,但是通过基类指针删除时,只有当基类有一个虚拟析构函数(声明virtual自己或者它自己的基类有一个虚拟析构函数)时,该实例才被正确地析构,该实例被正确地析构.

于 2012-01-30T20:09:57.913 回答