我的基类中有一个虚拟析构函数和一个数组。我怎样才能使它工作?

时间:2012-01-30 19:29:16

标签: c++ virtual-destructor

例如:

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? 
}

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

5 个答案:

答案 0 :(得分:9)

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

答案 1 :(得分:2)

当破坏派生对象并且基础的析构函数是虚拟的时,将调用两个析构函数。您可以在此处确认:http://ideone.com/RZamr

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

答案 2 :(得分:1)

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

希望这有帮助!

答案 3 :(得分: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()
     {
     }
  }

这将删除数组。

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

答案 4 :(得分:0)

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

只有一种情况并非如此:对基类的指针调用delete,其中基类析构函数虚拟。

在所有具有类的本地实例的情况下,在堆栈上创建,并且函数或方法退出,即使由于异常,实例也会被正确销毁。

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

当一个类的实例是new d但是通过基类指针删除时,只有当基类具有虚拟析构函数(或者声明为virtual本身或其自身)时,才会正确地破坏该实例自己的基础有一个虚拟的析构函数),实例被正确破坏。