virtual destructors for classes only with virtual functions?

H

heted7

Hi,

Most of the books on C++ say something like this: "A virtual destructor
should be defined if the class contains at least one virtual member
function."

My question is: why is it only for the case when the class contains at
least one virtual member function? Shouldn't the destructor always be
virtual, whenever there's a possibility that an inherited object will
be destructed through a base class pointer? (This does not require,
that the base class have any other virtual function!)

Thanks!

ps: can someone please explain me briefly, why a concrete base class
cannot have an abstract derived class?
 
?

=?ISO-8859-15?Q?Juli=E1n?= Albo

heted7 said:
My question is: why is it only for the case when the class contains at
least one virtual member function? Shouldn't the destructor always be
virtual, whenever there's a possibility that an inherited object will
be destructed through a base class pointer? (This does not require,
that the base class have any other virtual function!)

Because it will be uncommon that you wants to destroy polimorphically
objetcts that are not used polimorphically, and the majority of the books
talks about more common cases. And to add it to class in this case has some
overhead and many people does not want to pay this price.

But if you have reasons to add a virtual destructor, do it. The books says
that in that case you must add it, not that you must not do it in any other
case.
 
P

Pete Becker

Julián Albo said:
But if you have reasons to add a virtual destructor, do it. The books says
that in that case you must add it, not that you must not do it in any other
case.

And, just as not saying there are other cases where you need it is an
oversimplification, saying that you always need it when you have virtual
functions is an oversimplification.
 
E

E. Robert Tisdale

heted7 said:
Most of the books on C++ say something like this,
"A virtual destructor should be defined
if the class contains at least one virtual member function."

This is generally bad advice. Ignore it.
My question is, "Why is it only for the case
when the class contains at least one virtual member function?"
Shouldn't the destructor always be virtual whenever there's a possibility
that an inherited object will be destructed through a base class pointer?
(This does not require, that the base class have any other virtual function!)

Don't define a virtual destructor unless you have a specific use for it.
Generally, C++ functions shouldn't be destroying objects passed to them
by reference (or by reference through a pointer).
 
P

Peter Koch Larsen

E. Robert Tisdale said:
This is generally bad advice. Ignore it.
That's simply not true. The destructor SHOULD be virtual unless you have a
compelling reason for it not being so. The only compelling reason i can
think of would be performance-related. So unless you profile your code and
decide that the overhead of the virtual function is excessive (and with a
good compiler, there should be no overhead if the type is statically known),
do keep that destructor virtual.
Don't define a virtual destructor unless you have a specific use for it.
Generally, C++ functions shouldn't be destroying objects passed to them
by reference (or by reference through a pointer).
Also I recommend that if you have a class with virtual functions and no
virtual destructor, you sohuld remove the new-operator for that class. If
the class is meant to be used by others, this is nearly a must.

/Peter
 
P

Peter Koch Larsen

E. Robert Tisdale said:

When you create a class with a virtual function, by definition you are going
to use that class in a polymorphic way. In that case it is reasonable to
expect some user of that class to delete an object derived from that class
by calling the destructor with only access to your base-class. You might not
anticipate any such need, but having a virtual destructor enables that
feature. So lets have a look at the cost.
A virtual destructor is expensive in a class that does not already have
virtual functions: the vtable entry incurs an extra cost for every object
created. If you already have a virtual function this cost disappears, so the
added storage cost becomes practically zero. As for runtime costs, there
should not be any overhead either. The compiler will not have to call the
destructor using the vtable when the type of the object is statically known.
All in all it thus looks that all you save is one entry in the V-table,
which is something on the order of four to eight bytes. That is not per
object but for the entire program.
Thus the virtual destructor comes almost free in your case, and - as i
stated in my previous post - unless you have some compelling reason not to
make the destructor virtual you should let it be virtual.

/Peter
 
P

Peter Koch Larsen

Pete Becker said:
To increase code bloat, of course.

Hi Pete!

If you're serious, could you then explain why a virtual destructor causes
"code bloat", considering the class in question already had a virtual
function?

/Peter
 
B

ben

Now, the virtual destructor is there in a class if and only if the class is
meant to be, and in fact is, inherited by other classes. If the class is a
concrete type which is not meant to be, and in fact is not, inherited by
other classes, then virtualityof the destructor, like the virtuality of
other member functions, becomes redundant.

A virtual function usually signifies a polymorphic type. In this context a
virtual destructor is needed because the class is meant to be inherited.
There are always exceptions, especially with alternative object destruction
scheme is anticipated (for example, the Component Object Model).

Whether to used a virtual or non-virtual destructor shouldn't be a concern
of the whether the base type is polymorphic. If the base type is
polymorphic, it should have a virtual destructor and your destructor will be
virtual anyways. Otherwise if the base type is not a polymophic type then it
is not meant to be inherited, you may instead consider whether inheriting
from this particular base is a proper design choice.

ben
 
S

Samee Zahur

Can I ask another related question here?

Is it safe to destroy a derived object through a base class'
non-virtual destructor if the derived object has no data member of it's
own? (Provided, ofcourse, that the derived class makes no other extra
resource allocation like dynamic memory, file opening, network
connection ... etc, etc.)

Samee
 
P

Pete Becker

Peter said:
If you're serious, could you then explain why a virtual destructor causes
"code bloat", considering the class in question already had a virtual
function?

The destructor has to be generated out of line so that it's address can
be stored in the vtable. Even if it does nothing.
 
P

Pete Becker

Peter said:
When you create a class with a virtual function, by definition you are going
to use that class in a polymorphic way. In that case it is reasonable to
expect some user of that class to delete an object derived from that class
by calling the destructor with only access to your base-class. You might not
anticipate any such need, but having a virtual destructor enables that
feature.

And, by the same argument, all functions should be virtual, because you
just never know. The obvious flaw in that argument is that you're the
designer, and it's your job to know. Your customers shouldn't have to
pay for a feature that they won't use. If the design of your class does
not call for deleting through pointers to base it shouldn't have a
virtual destructor.
 
P

Pete Becker

Samee said:
Can I ask another related question here?

Is it safe to destroy a derived object through a base class'
non-virtual destructor if the derived object has no data member of it's
own? (Provided, ofcourse, that the derived class makes no other extra
resource allocation like dynamic memory, file opening, network
connection ... etc, etc.)

No. The rule is simple: if the design of a base class calls for deleting
objects of derived types through a pointer to the base, then the base
must have a virtual destructor. A common oversimplification is that if a
class has virtual functions it should have a virtual destructor, but
that errs in both directions: it calls for virtual destructors in some
cases where they aren't needed, and it doesn't call for virtual
destructors in some cases where they are needed.
 
P

Peter Koch Larsen

Pete Becker said:
And, by the same argument, all functions should be virtual, because you
just never know.
If you read my post again, you will see that your argument does not hold
water. I specifically made a distinction between classes with virtual
functions and classes without. By having a virtual function you state that
your class is to be used polymorphically, and then the specific advice -
have a virtual destructor unless you have good arguments that it should not
be so - holds.
The obvious flaw in that argument is that you're the designer, and it's
your job to know. Your customers shouldn't have to pay for a feature that
they won't use. If the design of your class does not call for deleting
through pointers to base it shouldn't have a virtual destructor.

Right. And in that case I advocated that you prevented new-ing the class
directly by making the new-operator private. If there still is a case for
dynamic allocation, you can always provide static methods.
/Peter
 
P

Pete Becker

Peter said:
If you read my post again, you will see that your argument does not hold
water. I specifically made a distinction between classes with virtual
functions and classes without. By having a virtual function you state that
your class is to be used polymorphically, and then the specific advice -
have a virtual destructor unless you have good arguments that it should not
be so - holds.

If you read my post again, you will see that your argument does not hold
water. I specifically said that the reason for having a virtual
destructor is that your design calls for deleting objects of derived
types through pointers to the base. That is not the same as having or
not having other virtual functions, nor does it have anything to do with
being "used polymorhpically."
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,202
Messages
2,571,057
Members
47,667
Latest member
DaniloB294

Latest Threads

Top