Деструкторы и наследование в C++?

Я использую Borland C++ Builder.

И у меня была проблема

#include <Classes.hpp>
class TMyObject : public TObject
{
   __fastcall TMyObject();
   __fastcall ~TMyObject();//I would like to inherite my destructor from TObject
};

__fastcall TMyObject::TMyObject() : TObject()//it will inherited my constructor from TObject
{
}

И для этого нового деструктора, который унаследует ~TObject?

__fastcall TMyObject::~TMyObject?????????????

4 ответа

Решение

Это может быть решено в TObjectуровень. Его деструктор должен быть виртуальным:

#include <Classes.hpp>
class TObject 
{
   __fastcall TObject();
   virtual __fastcall ~TObject(); 
};

Таким образом, вы можете сделать:

TObject * pobj = new TMyObject();
delete pobj;

или же

TMyObject * pobj = new TMyObject();
delete pobj;

Оба деструктора будут называться (~TMyObject() сначала, а потом ~TObject()) и у вас не будет утечки.

Деструктор базового класса будет автоматически вызываться компилятором, когда закончится время жизни вашего объекта. вам не нужно называть это явно.

TMyObject::TMyObject() : TObject()

Не наследует конструктор.
Он называется списком инициализатора члена и инициализирует объект базового класса определенным значением.

Когда вы создаете объект.

TMyObject obj;

Конструкторы будут вызываться по порядку:

constructor of TObject
constructor of TMyObject 

По истечении времени жизни объекта деструкторы будут вызываться в следующем порядке:

destructor of TMyObject 
destructr of TObject

Компилятор сделает это за вас, не нужно вызывать его явно.

Если вы уничтожите TMyObject через ссылку типа TMyObject тебе не нужно ничего делать. Если у вас есть указатель / ссылка типа TObject к TMyObject все пойдет не так. Только TObject будет называться деструктор, а не TMyObject один:

TObject* p = new TMyObject;
delete p; // Only the TObject::~TObject is called, not TMyObject::~TMyObject.

Чтобы решить, какой деструктор вызывать, отложить до времени выполнения, вам нужно указать деструктор как virtual в TObject, Всякий раз, когда у вас есть класс, от которого предполагается получить наследник, деструктор должен быть виртуальным. В противном случае всегда существует риск утечки ресурсов, когда деструктор производного класса не вызывается должным образом.

Что приводит вас в замешательство, так это то, что вы можете указать "какой" конструктор базового класса, который вы хотите использовать, как в следующем примере. Но вы не можете / не должны указывать деструктор.

TMyObject::TMyObject() : TObject()

Вы можете использовать другой конструктор, скажем, TObject (int i) написав

TMyObject::TMyObject() : TObject (3)

Объект может быть уничтожен только одним способом, но он может быть построен несколькими способами (с помощью разных конструкторов).

Короче говоря, вам не нужно упоминать имя деструктора базового класса в деструкторе производного класса. Как только вы уничтожите производный объект (скажем, делая delete derivedObj), он сначала вызовет деструктор производного класса, а затем сам деструктор базового класса.

Другие вопросы по тегам