Board index » cppbuilder » Calling virtual functions in destructors (use BCB for test)

Calling virtual functions in destructors (use BCB for test)


2003-09-29 11:35:01 PM
cppbuilder107
Hi,
Please have a look at the code below,
class Base
{
public:
virtual ~Base(){Func();}
virtual void __fastcall Func(void){ShowMessage("Base");}
};
class Derived : public Base
{
public:
virtual ~Derived(){}
virtual void __fastcall Func(void){ShowMessage("Derived");}
};
I expect that the function "Func" of the derived class called during destruction of the derived object. But if you run this code (using BCB), you will see that the virtual function does not called as I expected. Why? If the Borland compiler destruct Virtual Method Tables before object destruction?
Regards,
 
 

Re:Calling virtual functions in destructors (use BCB for test)

This newsgroup is about Borland C++, not C++ Builder.
Please direct your browser at info.borland.com/newsgroups/ and read the
newsgroup descriptions and guidelines. This will help you find the appropriate
newsgroup for your future questions.
"H.R." < XXXX@XXXXX.COM >writes:
Quote
class Base
{
public:
virtual ~Base(){Func();}
virtual void __fastcall Func(void){ShowMessage("Base");}
};
class Derived : public Base
{
public:
virtual ~Derived(){}
virtual void __fastcall Func(void){ShowMessage("Derived");}
};

I expect that the function "Func" of the derived class called during
destruction of the derived object.
Your expectations are wrong.
Quote
But if you run this code (using BCB),
you will see that the virtual function does not called as I expected. Why?
If a virtual function is called, the dynamic type of the object to which the
function is applied is taken into account.
If a virtual function for an object is called during its construction or
destruction, its dynamic type is the class that the constructor or destructor
currently executed belongs to.
When the Func() call from the destructor of Base is executed, the dynamic
type is thus Base; this means that Base::Func() will be selected. If you had
a Base construtor calling Func(), Base::Func() would be selected as well.
Quote
If the Borland compiler destruct Virtual Method Tables before object
destruction?
During the construction of an object, the pointer to the virtual member
function is adjusted as the constructors are executed. During its destruction,
the same adjustment happens, but in the reverse order.
The reason for all this is that if class Derived had a data member, its
destructor would already have been executed when Func() is called from the
Base destructor. If Derived::Func() were called, it could inadvertently access
that already destructed data member, which would have drastic consequences.
This is a difference between Java and C++, BTW. I've heard of Java programmers
that they had problems because their programs accessed not yet constructed
data member because in a constructor, a method of a class was selected whose
constructor hadn't been executed yet.
 

Re:Calling virtual functions in destructors (use BCB for test)

Thomas Maeder [TeamB] wrote:
Quote
>class Base
>{
>public:
>virtual ~Base(){Func();}
>virtual void __fastcall Func(void){ShowMessage("Base");}
>};
>class Derived : public Base
>{
>public:
>virtual ~Derived(){}
>virtual void __fastcall Func(void){ShowMessage("Derived");}
>};

The reason for all this is that if class Derived had a data member, its
destructor would already have been executed when Func() is called from the
Base destructor. If Derived::Func() were called, it could inadvertently access
that already destructed data member, which would have drastic consequences.
What would happen if Base::Func() were pure virtual?
 

{smallsort}

Re:Calling virtual functions in destructors (use BCB for test)

Bob Gonder < XXXX@XXXXX.COM >writes:
Quote
What would happen if Base::Func() were pure virtual?
The behavior would be undefined. Even if there were a definition.