execute constructor of derived class

Started by
11 comments, last by Bregma 8 years, 5 months ago

struct TObjectPropertyEditor : public TForm
{
TEntity * apply_to;
TObjectPropertyEditor()
{
apply_to = NULL;
}


~TObjectPropertyEditor() {}
};
now i woulld like to call TForm Constructor or maybe its called anyway?
same for destructor i don't know if its called along with ~TObjectPropertyEditor()
Advertisement

You want to call the constructor of TForm in TObjectPropertyEditor?

The TForm ctor will be called with TObjectPropertyEditor, the same with the dtor, unless you call delete on a TForm ptr that points to a TObjectPropertyEditor instance.

In that case you need to set a virtual dtor in TForm.

EDIT: Whoever down-voted do you care to explain why?

Your code and your words don't quite match up.

TObjectPropertyEditor is derived from TForm. That means TForm is the parent class, and TObjectPropertyEditor is the derived class.

When the objects are created, the TForm constructor is executed and run completely before TObjectPropertyEditor constructor is run. Base class constructors are called first, in the order they are listed in the class definition, then the constructors of sub objects are called in order, then the current class constructor is called.

Your constructor initializer lists should be in the same order the members appear. If you have five or ten members getting initialized, put the base constructor first and the member variables in order, the same order they appear top to bottom in the class file.

If you need to pass parameters or initialize variables, you can do it using a constructor initializer list, something like this:


struct TObjectPropertyEditor : public TForm
{
TEntity * apply_to;
TObjectPropertyEditor() : TForm(), apply_to(NULL)
{
}

//Adding this one as an example
//If you want to pass a parameter to a base class, you can do it like this
TObjectPropertyEditor(TController *controller) : TForm(controller), apply_to(NULL)
{
}

// Double check that your base class destructor is virtual and public.
~TObjectPropertyEditor() {}
};

When you create a TObjectPropertyEditor it will first call TForm's constructor, and after the TForm is created the above code will initialize apply_to with the value NULL, then it will run the TObjectPropertyEditor constructor body.

In the second constructor I wrote as an example, it will pass the parameter on to the TForm constructor and run the constructor, then initialize the variable to NULL, then run the constructor body.

Base class destructors -- which should usually be virtual and public, are automatically called. A class that is free standing can have a regular function for a destructor, but base classes have some special rules. Nearly always, and always when you intend to use polymorphic behavior for the class, a base class destructor needs to be public and virtual.

These destructors are an exception to the normal rule because they automatically call their base class variant, you don't need to call them.

Without that special rule you would need to write:


~TObjectPropertyEditor() {}
 // My own destruction
 ...

 TForm::~TForm();   // DON'T DO THIS, Don't chain virtual destructors, the compiler does it for you.
};

In any other case if you need to call the behavior of a virtual class you would need to chain it manually. Destructors are a special case, just make sure the base class destructor is virtual and they will all get destroyed in the correct order, ~TObjectPropertyEditor gets called first, then ~TForm is called next.

yeah my bad,

so once again


struct TObjectPropertyEditor : public TForm
{
TEntity * apply_to;
TObjectPropertyEditor() //TForm constructor will be executed right?
{
apply_to = NULL;
}


~TObjectPropertyEditor() {} //TForm desctructor will be executed right?
};

i expect simple yes or now now :) because i ididnt understand your replies too


TObjectPropertyEditor() //TForm constructor will be executed right?

Yes.


~TObjectPropertyEditor() {} //TForm desctructor will be executed right?

Yes with a caveat.

If the function is not marked as virtual, it is possible for the TForm destructor to be called but the TObjectPropertyEditor not get called.

So that works only if the TForm destructor is virtual, which it should be. Virtual gets inherited, so if TForm derived from something and it was marked virtual, that would also make it happen.

If it is not virtual, than this won't work:


base* b;
b=new derived;
delete b;

In that case if the destructor is not virtual than the derived destructor won't be called, only the base constructor is called.

If the base class destructor is virtual then both the base destructor and derived destructor will be called.

Or more specific to your example:


TForm* form;
form=BuildSomePropertyEditor();
...
delete form;

In that case if the destructor is not virtual only the TForm destructor would be called, which is a bug.

If the destructor is virtual then when the object is deleted the TObjectPropertyEditor destructor gets called, then TForm destructor gets called, which is what you want.

So make sure the base class destructor is virtual, otherwise there can be serious problems.

TObjectPropertyEditor something;

now when i end program its destructor is called i want to call (TForm destructor too) so you say i should write: virtual ~TForm() { code for TForm destructor } ?

TObjectPropertyEditor something;

now when i end program its destructor is called i want to call (TForm destructor too) so you say i should write: virtual ~TForm() { code for TForm destructor } ?

Strictly speaking, in this case, you don't need to.

If you create a derived object on the stack, then both destructors will be called on exit of the scope.

However, in general, it's considered good practice to make base class destructors virtual.

Also, for the love of the FSM, use some goddamn punctuation! Capitals, commas, periods, etc. make text a lot easier to read.

if you think programming is like sex, you probably haven't done much of either.-------------- - capn_midnight

The typical rule of thumb is that a C++ class with any virtual member functions should also have a virtual destructor. Note that this also means specifying an empty virtual destructor even where you don't actually need custom destruction logic. This is based on the reasoning that writing code like frob demonstrated is typically only useful if the class in question has virtual member functions worth calling.

i still don't quite get it can we go over another example

struct TForm

{

virtual void Draw()

{

draw form background

}

}

struct TObjectPropertyEditor : public TForm
{

void Draw()

{

//draw controls defined in ObjectPrpertyEditor struct

}
};

will Draw from TObjectPropertyEditor, call Draw() from TForm first and then call Draw in TObjectPropertyEditor ?


will Draw from TObjectPropertyEditor, call Draw() from TForm first and then call Draw in TObjectPropertyEditor ?

No. Constructors and destructors are different from regular functions in that they are called for all parents that a class inherited from.

For regular virtual fuctions, only the last overwritten one will be called. So if you have an object of type "TObjectPropertyEditor" and call "Draw" on it, TObjectPropertyEditor::Draw will ultimately be called. If you want to enforce the parents implementation to be called, you can do:


struct TObjectPropertyEditor : public TForm
{

void Draw()

{

    TForm::Draw();

}
};

This will explicitely call the function as defined in TForm.

This topic is closed to new replies.

Advertisement