Destructors and inheritance in C++?
Asked Answered
C

4

7

I use Borland C++ Builder.

And i had 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
{
}

And for that new destructor that will inherite ~TObject?

__fastcall TMyObject::~TMyObject?????????????
Counterinsurgency answered 28/7, 2011 at 9:4 Comment(0)
B
4

This can be solved at TObject's level. Its destructor has to be virtual:

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

This way you can either do:

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

or

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

Both destructors will be called (~TMyObject() first and then ~TObject()) and you will have no leak.

Babu answered 28/7, 2011 at 9:29 Comment(5)
TObject is a Borland-provided system class, and it does have a virtual destructor.Messner
Ok! So there shouldn't be any issue here: ~TMyObject() and ~TObject() should be called without us to do anything specific.Babu
So the question has no basis, finally?Babu
Yes. The original code snippet will work just fine as-is. ~TMyObject() is called automatically when the object is freed, and the compiler will handle calling ~TObject() at the end of ~TMyObject().Messner
I agree with Remy but I think ~TMyObject() should be virtual.Rigi
U
4

Destructor of the Base class will be automatically called by the compiler, when your objet life time ends. you do not need to call it explicitly.

TMyObject::TMyObject() : TObject()

Does not inherit the constructor.
It is called as Member initializer list and it initializes the Base class object with a particular value.

When you create the object.

TMyObject obj;

The constructors will be called in order:

constructor of TObject
constructor of TMyObject 

When the object life time ends the destructors will be called in the order:

destructor of TMyObject 
destructr of TObject

The compiler will do so for you, do not need to call it explicitly.

Unicycle answered 28/7, 2011 at 9:6 Comment(3)
I would like something like that:Counterinsurgency
@user558126: I am afraid that is not possible.Unicycle
No, this is not possible. You don't have to explicitely call the destructor of TObject anyway, as there is no placement new here. But what you are mentioning (execution of ~TMyObject() followed by execution of ~TObject()) is done automatically by the use of virtual at ~TObject() level.Babu
B
4

This can be solved at TObject's level. Its destructor has to be virtual:

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

This way you can either do:

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

or

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

Both destructors will be called (~TMyObject() first and then ~TObject()) and you will have no leak.

Babu answered 28/7, 2011 at 9:29 Comment(5)
TObject is a Borland-provided system class, and it does have a virtual destructor.Messner
Ok! So there shouldn't be any issue here: ~TMyObject() and ~TObject() should be called without us to do anything specific.Babu
So the question has no basis, finally?Babu
Yes. The original code snippet will work just fine as-is. ~TMyObject() is called automatically when the object is freed, and the compiler will handle calling ~TObject() at the end of ~TMyObject().Messner
I agree with Remy but I think ~TMyObject() should be virtual.Rigi
C
1

If you destroy a TMyObject through a reference of type TMyObject you don't have to do anything. In case you have a pointer/reference of type TObject to a TMyObject things will go wrong. Only the TObject destructor will be called, not the TMyObject one:

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

To have the decision on what destructor to call deferred to runtime, you need to specify the destructor as virtual in TObject. Whenever you have a class that is intended to be derived from, the destructor should be virtual. Otherwise there is always a risk for resource leaks when the derived class destructor isn't called properly.

Capture answered 28/7, 2011 at 9:11 Comment(0)
U
1

What's causing the confusion to you is that you can specifically mention "which" constructor of the base class you want to use as in the following example. But you can't/ don't need to specify the destructor.

TMyObject::TMyObject() : TObject()

You could use a different constructor, say TObject (int i) by writing

TMyObject::TMyObject() : TObject (3)

An object can be destructed in only one way but it can be constructed in several ways (by having different constructors).

So, in short, you don't need to mention the name of the base class destructor in the derived class destructor. As soon as you destroy the derived object (say, by doing delete derivedObj), it will first call the derived class destructor and then base class destructor by itself.

Upcast answered 28/7, 2011 at 9:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.