Деструкторы и наследование в C ++? - PullRequest
5 голосов
/ 28 июля 2011

Я использую 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 ]

4 голосов
/ 28 июля 2011

Это можно решить на уровне 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()) и утечки не будет.

4 голосов
/ 28 июля 2011

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

TMyObject::TMyObject() : TObject()

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

При создании объекта.

TMyObject obj;

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

constructor of TObject
constructor of TMyObject 

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

destructor of TMyObject 
destructr of TObject

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

1 голос
/ 28 июля 2011

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

TMyObject::TMyObject() : TObject()

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

TMyObject::TMyObject() : TObject (3)

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

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

1 голос
/ 28 июля 2011

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

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

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

...