virtual destructors for classes only with virtual functions?

Discussion in 'C++' started by heted7, May 8, 2005.

  1. heted7

    heted7 Guest

    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?
     
    heted7, May 8, 2005
    #1
    1. Advertising

  2. heted7 wrote:

    > 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.

    --
    Salu2
     
    =?ISO-8859-15?Q?Juli=E1n?= Albo, May 8, 2005
    #2
    1. Advertising

  3. heted7

    Pete Becker Guest

    Julián Albo wrote:
    >
    > 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.

    --

    Pete Becker
    Dinkumware, Ltd. (http://www.dinkumware.com)
     
    Pete Becker, May 8, 2005
    #3
  4. heted7

    heted7 Guest

    Thanks for both of you!
     
    heted7, May 8, 2005
    #4
  5. heted7

    Abecedarian Guest

    Pete Becker wrote:
    > saying that you always need it when you have virtual
    > functions is an oversimplification.


    An example, please!

    ::A::
     
    Abecedarian, May 8, 2005
    #5
  6. heted7 wrote:

    > 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).
     
    E. Robert Tisdale, May 8, 2005
    #6
  7. heted7

    Abecedarian Guest

    heted7 wrote:
    > 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 a good rule of thumb. Don't ignore it.
    See also: http://www.artima.com/cppsource/bigtwo.html

    ::A::
     
    Abecedarian, May 8, 2005
    #7
  8. "E. Robert Tisdale" <> skrev i en meddelelse
    news:d5m1pn$bfd$...
    > heted7 wrote:
    >
    >> 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!)

    >

    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
     
    Peter Koch Larsen, May 8, 2005
    #8
  9. Peter Koch Larsen wrote:

    > The destructor SHOULD be virtual
    > unless you have a compelling reason for it not being so.


    Why?
     
    E. Robert Tisdale, May 8, 2005
    #9
  10. heted7

    Pete Becker Guest

    E. Robert Tisdale wrote:
    > Peter Koch Larsen wrote:
    >
    >> The destructor SHOULD be virtual
    >> unless you have a compelling reason for it not being so.

    >
    >
    > Why?


    To increase code bloat, of course.

    --

    Pete Becker
    Dinkumware, Ltd. (http://www.dinkumware.com)
     
    Pete Becker, May 9, 2005
    #10
  11. Pete Becker wrote:

    > E. Robert Tisdale wrote:
    >
    >> Peter Koch Larsen wrote:
    >>
    >>> The destructor SHOULD be virtual
    >>> unless you have a compelling reason for it not being so.

    >>
    >> Why?

    >
    > To increase code bloat, of course.


    It was a "straight-up" question.
     
    E. Robert Tisdale, May 9, 2005
    #11
  12. "E. Robert Tisdale" <> skrev i en meddelelse
    news:d5m5je$dbp$...
    > Peter Koch Larsen wrote:
    >
    >> The destructor SHOULD be virtual
    >> unless you have a compelling reason for it not being so.

    >
    > Why?


    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
     
    Peter Koch Larsen, May 9, 2005
    #12
  13. "Pete Becker" <> skrev i en meddelelse
    news:...
    > E. Robert Tisdale wrote:
    >> Peter Koch Larsen wrote:
    >>
    >>> The destructor SHOULD be virtual
    >>> unless you have a compelling reason for it not being so.

    >>
    >>
    >> Why?

    >
    > To increase code bloat, of course.
    >
    > --
    >
    > Pete Becker
    > Dinkumware, Ltd. (http://www.dinkumware.com)


    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
     
    Peter Koch Larsen, May 9, 2005
    #13
  14. heted7

    ben Guest

    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

    > 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!)
     
    ben, May 9, 2005
    #14
  15. heted7

    Samee Zahur Guest

    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
     
    Samee Zahur, May 9, 2005
    #15
  16. heted7

    Pete Becker Guest

    Peter Koch Larsen wrote:
    >
    > 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.

    --

    Pete Becker
    Dinkumware, Ltd. (http://www.dinkumware.com)
     
    Pete Becker, May 9, 2005
    #16
  17. heted7

    Pete Becker Guest

    Peter Koch Larsen wrote:

    >
    > 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.

    --

    Pete Becker
    Dinkumware, Ltd. (http://www.dinkumware.com)
     
    Pete Becker, May 9, 2005
    #17
  18. heted7

    Pete Becker Guest

    Samee Zahur wrote:

    > 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.

    --

    Pete Becker
    Dinkumware, Ltd. (http://www.dinkumware.com)
     
    Pete Becker, May 9, 2005
    #18
  19. "Pete Becker" <> skrev i en meddelelse
    news:...
    > Peter Koch Larsen wrote:
    >
    >>
    >> 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.

    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.
    >
    > --
    >
    > Pete Becker
    > Dinkumware, Ltd. (http://www.dinkumware.com)


    /Peter
     
    Peter Koch Larsen, May 9, 2005
    #19
  20. heted7

    Pete Becker Guest

    Peter Koch Larsen wrote:
    >
    > 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."

    --

    Pete Becker
    Dinkumware, Ltd. (http://www.dinkumware.com)
     
    Pete Becker, May 9, 2005
    #20
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. qazmlp
    Replies:
    7
    Views:
    495
    Howard
    Jul 27, 2004
  2. Peter
    Replies:
    6
    Views:
    376
  3. Replies:
    3
    Views:
    378
    Nitin Motgi
    Jan 31, 2006
  4. Pravesh
    Replies:
    3
    Views:
    332
    Pravesh
    Jun 20, 2006
  5. Henrik Goldman
    Replies:
    6
    Views:
    600
    terminator
    Nov 19, 2006
Loading...

Share This Page