2011-07-28 24 views
5

Używam Borland C++ Builder.Destruktory i dziedziczenie w C++?

i miałem o Problem

#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 
{ 
} 

a do tego nowego destructor, które inherite ~TObject?

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

Odpowiedz

4

Można to rozwiązać na poziomie TObject. Jego destruktor musi być wirtualny:

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

W ten sposób można też zrobić:

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

lub

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

obu destruktorów zostanie wywołana (~TMyObject() a potem ~TObject()) i nie będzie miał przecieku.

+0

'TObject' jest klasą systemową dostarczaną przez firmę Borland i ma wirtualny destruktor. –

+0

OK! Tak więc nie powinno tu być żadnych problemów: ~ TMyObject() i ~ TObject() powinny być wywoływane bez nas, aby zrobić coś konkretnego. – Shlublu

+0

Prawidłowe i działa tak, jak oczekiwano. –

4

Destruktor klasy Base zostanie automatycznie wywołany przez kompilator, gdy zakończy się okres przydatności do użycia. nie musisz tego wyraźnie wywoływać.

TMyObject::TMyObject() : TObject() 

Nie dziedziczy konstruktora.
Nazywa się to jako Member initializer list i inicjuje obiekt klasy Base o określonej wartości.

Po utworzeniu obiektu.

TMyObject obj; 

konstruktorów zostanie wywołana w celu:

constructor of TObject 
constructor of TMyObject 

Kiedy kończy się czas życia obiektu destruktory zostanie wywołana w kolejności:

destructor of TMyObject 
destructr of TObject 

kompilator zrobi to za ty, nie musisz tego wyraźnie wywoływać.

+0

Chciałbym coś takiego: – user558126

+0

__fastcall TMyObject :: ~ TMyBoejct(): ~ TObject() {nowy kod} – user558126

+0

@ user558126: Obawiam się, że to niemożliwe. –

1

Jeśli zniszczysz TMyObject przez odniesienie typu TMyObject, nie musisz nic robić. Jeśli masz wskaźnik/odniesienie typu TObject do TMyObject, wszystko pójdzie nie tak. TylkoTObject destruktor zostanie wywołany, a nie TMyObject jeden:

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

Aby mieć decyzję, co do destructor zadzwoń odroczone do wykonywania, należy określić destruktora jako virtual w TObject. Ilekroć masz klasę, która ma zostać wyprowadzona, destruktor powinien być wirtualny. W przeciwnym razie zawsze istnieje ryzyko przecieku zasobów, gdy destruktor klasy pochodnej nie jest poprawnie wywoływany.

+0

+1 za wymienienie wirtualnego destruktora – Jaywalker

1

To, co powoduje zamieszanie, polega na tym, że możesz konkretnie wymienić "który" konstruktor klasy bazowej, którego chcesz użyć, jak w poniższym przykładzie. Ale nie można/nie trzeba określać destruktora.

TMyObject::TMyObject() : TObject() 

Można użyć innego konstruktora, powiedzmy TObject (int i) pisząc

TMyObject::TMyObject() : TObject (3) 

obiekt może zostać zniszczone tylko w jeden sposób, ale może być wykonana na kilka sposobów (poprzez różne konstruktorów).

Krótko mówiąc, nie trzeba podawać nazwy destruktora klasy podstawowej w destruktorze klasy pochodnej. Zaraz po zniszczeniu obiektu pochodnego (powiedzmy, wykonując delete derivedObj), najpierw wywoła się destruktor klasy pochodnej, a następnie sam destruktor klasy podstawowej.