简体   繁体   中英

I have a virtual destructor and an array in my base class. How can I make it work?

Ex:

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

I have a virtual destructor and an array in my base class. If the base class destructor is overridden by the derived class destructor, then the basearray won't get deleted. What's a nice solution?

基类的析构函数自动调用,派生类的析构函数运行之后。

When destructing a derived object and the destructor of the base is virtual, both destructors will be called. You can confirm this here: http://ideone.com/RZamr

The order will be opposite to the order of constructors, ie when constructing first a constructor of base will be called, then on of derived . When destructing first the destructor of derived will be called, then the one of base .

Virtual destructors don't work the same way that other virtual functions do in that a base class's virtual destructor is never overridden. Instead, when a subclass provides their own destructor, that subclass destructor fires, then the base class destructor fires as well. The "virtual" here is used so that if you delete a derived class object through a base class pointer, C++ knows to call the destructor based on the dynamic type of the object (the subclass) rather than the static type of the pointer (the superclass). As a result, you don't need to do anything special here. The base class destructor will work as usual.

Hope this helps!

When overriding a destructor the base class destructor is still called as long as it is defined as 'virtual', which is what you have done.

So in this example:

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

     ~base()
     {
        delete[] myarray;
     }

  private:
     float* myarray;
  }


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

     ~derived()
     {
     }
  }

This will not delete 'myarray' and will leak memory because the base class destructor is hidden by the derived class destructor. However:

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

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

  private:
     float* myarray;
  }


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

     ~derived()
     {
     }
  }

This will delete the array.

Bear in mind that constructors are called from the base class up, so the base class constructor is called first, followed by the derived class, whereas destructors are called in the reverse order, so your derived class destructor is called before that of the base class.

There's no problem here. The base class destructor is called right after the derived class destructor is called.

There's only one circumstance where this is not true: delete is called on a pointer to the base class where the base class destructor is not virtual.

In all circumstances where you have a local instance of a class, created on the stack, and the function or method exits, even because of an exception, the instance is correctly destructed.

In all circumstances where an instance of a class is new d, and subsequently deleted through a pointer to the exact class that was instantiated, the instance is correctly destructed.

When an instance of a class is new d, but deleted through a base class pointer, the instance is only correctly destructed when the base class has a virtual destructor (either declared virtual itself or its own base has a virtual destructor), the instance is correctly destructed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM