> Programming Languages > C++
Various Topics Home | Disclaimer | Report Adult Posts

Various Topics on C++



C++ - "virtual destructor revisted" in Programming Languages


Old 06-20-2004   #1
..i..
 
Default virtual destructor revisted

A reason for declaring a "virtual destructor" for a Base cl*** is to make
sure the destructor of Derived cl*** will be invoked when a pointer of Base
type is used to delete an object of Derived.

Is this the only reason to define "virtual destructor" for a Base cl***?

Since it's always possible that users of any Base cl*** will delete a
Derived object like that, does this mean that a "virtual destructor" is
always necessary?

Thanks in advance!




 
Old 06-20-2004   #2
..l..
 
Default Re: virtual destructor revisted

ctick wrote:

> A reason for declaring a "virtual destructor" for a Base cl*** is to make
> sure the destructor of Derived cl*** will be invoked when a pointer of

Base
> type is used to delete an object of Derived.
>
> Is this the only reason to define "virtual destructor" for a Base cl***?
>
> Since it's always possible that users of any Base cl*** will delete a
> Derived object like that, does this mean that a "virtual destructor" is
> always necessary?
>
> Thanks in advance!


Make all destructors virtual unless profiling reveals you really really
really don't need one.

If your cl*** is abstract, with only pure virtual methods, make the
destructor pure virtual too.

Only one sequence of events leads to undefined behavior: A base cl*** has no
virtual destructor, you derive from it, create a 'new' derived object, take
this object's address, convert the address to the base type, and 'delete'.

'delete'ing a base type pointer is not a rare sequence of events in wildly
polymorphic designs. You should take greater care to ensure that the return
value of 'new' is always stored in a smart pointer or equivalent of the
correct derived type, so destruction becomes automatic. And plenty of
polymorphic designs use only the stack to store objects, so all these
situations destroy and clean up correctly.

However, refactors and new features could easily migrate a statically
allocated object into a dynamic one. At this time, nothing in your system
will tell you if your 'delete' creates undefined behavior (except possibly a
lint tool).

The language permits this loophole to permit tuning performance. Sometimes
the tiny overhead of a virtual method table hurts, so you can always take it
out. A keyword called "unvirtual" would be silly, so you must simply always
make destructors virtual.

--
Phlip
http://industrialxp.org/community/bi...UserInterfaces


 
Old 06-20-2004   #3
.... ..rris..
 
Default Re: virtual destructor revisted


"ctick" <ctick@flare.com> wrote in message
news:bZ8Bc.7621$OB3.2639@bgtnsc05-news.ops.worldnet.att.net...
> A reason for declaring a "virtual destructor" for a Base cl*** is to make
> sure the destructor of Derived cl*** will be invoked when a pointer of

Base
> type is used to delete an object of Derived.
>
> Is this the only reason to define "virtual destructor" for a Base cl***?


Pretty much yes. There is one other rather obscure reason. It might be that
you want cl*** Base to have at least one virtual function (so that you can
use dynamic_cast on it for instance) but you don't have any other suitable
method to declare as virtual.

>
> Since it's always possible that users of any Base cl*** will delete a
> Derived object like that, does this mean that a "virtual destructor" is
> always necessary?


Not really. There is an overhead to using virtual functions. If your cl***
is not intended to be used polymorphically then don't use any virtual
functions (including destructor) and do***ent that fact. Unfortunately its
always possible that users will do something stupid.

john


 
Old 06-20-2004   #4
.. ..be.. ..sda..
 
Default Re: virtual destructor revisted

Phlip wrote:

> ctick wrote:
>
>>A reason for declaring a "virtual destructor" for a Base cl***
>>is to make sure the destructor of Derived cl*** will be invoked
>>when a pointer of Base type is used to delete an object of Derived.
>>
>>Is this the only reason to define "virtual destructor" for a Base cl***?
>>
>>Since it's always possible that users of any Base cl***
>>will delete a Derived object like that, does this mean that
>>a "virtual destructor" is always necessary?

>
> Make all destructors virtual
> unless profiling reveals you really really really don't need one.


This is *very* bad advice.
If all C++ destuctors were meant to be virtual,
that feature would have been built into the language --
or the language would have been renamed Java.
 
Old 06-20-2004   #5
.. ..be.. ..sda..
 
Default Re: virtual destructor revisted

John Harrison wrote:

> There is an overhead to using virtual functions.


cl*** Base {
public:
virtual
~Base(void) { }
};

cl*** Derived: public Base {
public:
virtual
~Derived(void) { }
};

void blackHole(Base* p) {
delete [] p;
}

Derived* p = new Derived[bzillion];
blackHole(p);

The destructors do nothing and a good C++ compiler
could have optimized them away if they weren't virtual destructors
but, because the destuctor for the base cl*** was declared virtual,
the compiler will be forced to emit code to call the destructor
for Derived a bzillion times -- to do nothing!

> If your cl*** is not intended to be used polymorphically,
> then don't use any virtual functions (including destructor)
> and do***ent that fact.


Even if your cl*** *is* intended to be used polymorphically,
you really need a strong argument to include a virtual destructor.
 
Old 06-20-2004   #6
..v.. ..rm..
 
Default Re: virtual destructor revisted

On Sat, 19 Jun 2004 22:51:01 -0700 in comp.lang.c++, "E. Robert Tisdale"
<E.Robert.Tisdale@jpl.nasa.gov> wrote,
>
>This is *very* bad advice.
>If all C++ destuctors were meant to be virtual,
>that feature would have been built into the language --
>or the language would have been renamed Java.


Come on, Robert, you know it's only very ordinary everyday grade bad
advice. Sure it will make your programs slower and eat a bit more
memory for no good reason, but I can't think of a case where it will
make them give wrong answers or undefined behavior. And it might even
save somebody's clueless butt, once in a blue moon. I told you a
million times not to exaggerate.

 
Old 06-20-2004   #7
.... ..rs..
 
Default Re: virtual destructor revisted

"David Harmon" <source@netcom.com.invalid> wrote in message
news:40ec3bb0.36396009@news.west.earthlink.net
>
> I told you a
> million times not to exaggerate.





--
John Carson
1. To reply to email address, remove donald
2. Don't reply to email address (post here instead)
 
Old 06-20-2004   #8
....
 
Default Re: virtual destructor revisted

ctick posted:

> A reason for declaring a "virtual destructor" for a Base cl*** is to
> make sure the destructor of Derived cl*** will be invoked when a
> pointer of Base type is used to delete an object of Derived.
>
> Is this the only reason to define "virtual destructor" for a Base
> cl***?
>
> Since it's always possible that users of any Base cl*** will delete a
> Derived object like that, does this mean that a "virtual destructor" is
> always necessary?
>
> Thanks in advance!


Write your program. At the end, analyse it and see if you use a pointer of
type Base* to delete an object of type Derived . If so, declare ~Base
virtual. If not... DON'T! Very simple.


Where things get a little more complex is with reusable code. Let's say you
write a super duper special cl***:

cl*** SuperDuperSpecial;


You're not guaranteed that the "user" of your cl*** will not...(the
aformentioned).

Solution:

A) Just declare the destructor virtual.

B) Supply two forms:

cl*** SuperDuperSpecialVirtualDestructor;
 

Thread Tools
Display Modes





Powered by vBulletin®
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0