Topic: virtual destructors


Author: tgaunt@pms701.pms.ford.com (Ted Gaunt)
Date: Mon, 09 Jan 95 16:50:38 EST
Raw View
Recently when porting some code from Borland C++ to
GNU C++, gcc complained that some of my classes needed
to have virtual destructors (since those objects had
some virtual functions).  I blindly changed these classes
to conform.

How does a virtual destructor work differently than a normal one?

Does it mean that my destructor for inherited classes now need
to explicitly call their parent's destructor?

Please CC email me a copy of your response post.
--
-----------------------------------
|    Ted Gaunt                    |
|    Ann-Arbor, Michigan, USA     |
|    tgaunt@pms701.pms.ford.com   |
-----------------------------------





Author: b91926@fsgm01.fnal.gov (David Sachs)
Date: 9 Jan 1995 16:32:26 -0600
Raw View
tgaunt@pms701.pms.ford.com (Ted Gaunt) writes:

>Recently when porting some code from Borland C++ to
>GNU C++, gcc complained that some of my classes needed
>to have virtual destructors (since those objects had
>some virtual functions).  I blindly changed these classes
>to conform.

>How does a virtual destructor work differently than a normal one?

>Does it mean that my destructor for inherited classes now need
>to explicitly call their parent's destructor?

>Please CC email me a copy of your response post.
>--
You need a virtual destructor for a class if you intend to delete
a pointer to that class, that actually points to a subclass. The
virtuality of the destructor then causes the destructor of the
actual class type to be called (and it calls directly or indirectly
the destructor for all its bases).




Author: rmartin@rcmcon.com (Robert Martin)
Date: Tue, 10 Jan 1995 18:09:18 GMT
Raw View
tgaunt@pms701.pms.ford.com (Ted Gaunt) writes:

>Recently when porting some code from Borland C++ to
>GNU C++, gcc complained that some of my classes needed
>to have virtual destructors (since those objects had
>some virtual functions).  I blindly changed these classes
>to conform.

>How does a virtual destructor work differently than a normal one?

>Does it mean that my destructor for inherited classes now need
>to explicitly call their parent's destructor?

There are three (count 'em, three) reasons to use virtual destructors.

1.  Without a virtual destructor, the proper destructor may not be
called:

struct B {~B();};
struct D : B {~D();};
B* b = new D;
delete b; // <--------- Will not call D::~D() !!!!!

2. Without a virtual destructor, operator delete(void*, size_t) may
not be called with the correct size.

struct B {~B(); operator delete(void*, size_t);};
struct D : B {~D();};
B* b = new D;
delete b; // <--------- Will call operator delete(void*, size_t) with
          //            the size of B not the size of D!!!

3.  Without a virtual destructor, and when MI is used, operator
delete(void*) or operator delete (void*, size_t) may be called with
the wrong address.

struct B {~B();};
struct A {};
struct D : A, B {~D();};
B* b = new D;
delete b; // <--------- May not pass to operator delete the address
          //            that was returned by operator new!!!


All of these conditions are very deadly.  It does not matter if B is
an abstract base or not.  The same issues apply.  So ALWAYS use a
virtual destructor unless you have a very very good reason.

What is a good reason?  Well, you have a class like:

    struct TinyPoint
    {
      char x,y;
    };

This class takes up two bytes.  A virtual destructor will probably add
4 bytes to this for the vtbl pointer.  If you are going to allocate a
million of them, then you will have 2meg taken up by data, and 4meg
taken up by pointers, that all point to the same thing.  Thus, this is
probably a good case for not declaring a virtual destructor.

--
Robert Martin       | Design Consulting   | Training courses offered:
Object Mentor Assoc.| rmartin@rcmcon.com  |   Object Oriented Analysis
2080 Cranbrook Rd.  | Tel: (708) 918-1004 |   Object Oriented Design
Green Oaks IL 60048 | Fax: (708) 918-1023 |   C++




Author: swf@elsegundoca.ncr.com (Stan Friesen)
Date: Thu, 12 Jan 1995 17:20:15 GMT
Raw View
In article <1995Jan10.180918.17854@rcmcon.com>, rmartin@rcmcon.com (Robert Martin) writes:
|>
|> All of these conditions are very deadly.  It does not matter if B is
|> an abstract base or not.  The same issues apply.  So ALWAYS use a
|> virtual destructor unless you have a very very good reason.

The approach we use here is to diffgerentiate between classes intended
to be inherited from and those intended to be used as is.

We effectively require virtual destructors for the first group, but
not for the second.

[We also normally forbid inheriting from a class not intended as a base class].

--
swf@elsegundoca.attgis.com  sarima@netcom.com

The peace of God be with you.