Topic: Is a virtual destructor required in this case?


Author: stephen.clamage_nospam@eng.sun.com (Steve Clamage)
Date: 1997/11/10
Raw View
On 07 Nov 97 11:05:47 GMT, "Paul D. DeRocco" <pderocco@ix.netcom.com>
wrote:

>Steve Clamage wrote:
>>
>> The result of the code is formally undefined, and no diagnostic is
>> required. You can correctly delete an object via a pointer to a base
>> class only if the base class has a virtual destructor.
>>
>> In the specific example with empty classes, the code would probably
>> run without a problem on most (if not all) implementations. You just
>> can't depend on it.
>
>Shouldn't the standard specify that it's okay to do the above,
>as long as the derived classes don't add any nonstatic data
>members or additional base classes? It's not that uncommon to
>derive from a class without actually modifying its structure,
>perhaps to provide a modified interface to the class.

I don't think the standard should try to specify which bad programming
practices are nevertheless assured to work. (It does do so, but mainly
to keep C compatibility.) I claim that creating a hierarchy without a
virtual destructor in the base class(es) is a bad programming
practice. You have to include comments like "if you do any of the
following things, be sure to do this other thing too" and hope the
comments are noticed and obeyed. That is a recipe for problems down
the line. It is far better to do the right thing at the start. (What
is the cost of adding the virtual destructor? What are the costs and
benefits of not doing so?)

---
Steve Clamage, stephen.clamage_nospam@eng.sun.com
( Note: remove "_nospam" when replying )
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: stephen.clamage_nospam@eng.sun.com (Steve Clamage)
Date: 1997/11/07
Raw View
On 04 Nov 97 15:45:56 GMT, paul@ra.avid.com (Paul Miller) wrote:

>mlg@scr.siemens.com (Michael Greenberg) writes:
>
>>I believe the following is definitely incorrect.  (not that I think it
>>should be).
>
>>  class foo { } ;
>>  class bar : public foo { } ;
>>
>>  ...
>
>>  foo* f = new bar;
>>  delete f;
>
>>Is my understanding correct?
>
>You do not need a virtual destructor (or a destructor at all)
>if your class or any subclasses do not allocate any resources.

That is not so. If you delete an object via a pointer to base class
that lacks a virtual destructor, the results are undefined. In this
example with empty classes, it is likely the program will not have any
problems, but you cannot count on it.

>The general rule is that if your class will be derived from AT ALL,
>then you should make a virtual base class destructor.

Yes.

---
Steve Clamage, stephen.clamage_nospam@eng.sun.com
( Note: remove "_nospam" when replying )
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1997/11/07
Raw View
Steve Clamage wrote:
>
> The result of the code is formally undefined, and no diagnostic is
> required. You can correctly delete an object via a pointer to a base
> class only if the base class has a virtual destructor.
>
> In the specific example with empty classes, the code would probably
> run without a problem on most (if not all) implementations. You just
> can't depend on it.

Shouldn't the standard specify that it's okay to do the above,
as long as the derived classes don't add any nonstatic data
members or additional base classes? It's not that uncommon to
derive from a class without actually modifying its structure,
perhaps to provide a modified interface to the class.

It should even be feasible to allow the above even if additional
data members are added, as long as they don't have destructors.
The only requirement this would impose would be that operator
delete would have to be able to figure out how big an object
it's deleting with no guidance from the compiler. However, given
that operator delete typically calls free(), which has that
capability, this wouldn't be a problem.

--

Ciao,
Paul
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/11/04
Raw View
mlg@scr.siemens.com (Michael Greenberg) writes:

>I believe the following is definitely incorrect.  (not that I think it
>should be).
>
>  class foo { } ;
>  class bar : public foo { } ;
>
>  ...
>
>  foo* f = new bar;
>  delete f;
>
>Is my understanding correct?

The example above has undefined behaviour.
(See 5.3.5[expr.delete] paragraph 3.)
So yes, the example is incorrect.

If you change class `foo' to

   class foo {
   public:
  virtual ~foo() {}
   };

then it would be fine.

--
Fergus Henderson <fjh@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3         |     -- the last words of T. S. Garp.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: paul@ra.avid.com (Paul Miller)
Date: 1997/11/04
Raw View
mlg@scr.siemens.com (Michael Greenberg) writes:

>I believe the following is definitely incorrect.  (not that I think it
>should be).

>  class foo { } ;
>  class bar : public foo { } ;
>
>  ...

>  foo* f = new bar;
>  delete f;

>Is my understanding correct?

You do not need a virtual destructor (or a destructor at all)
if your class or any subclasses do not allocate any resources. Your
example above is kind of bad since they are empty, and in the real
world wouldn't need destructors as written.

The general rule is that if your class will be derived from AT ALL,
then you should make a virtual base class destructor.


>Michael Greenberg                      email: mgreenberg@scr.siemens.com
>Siemens Corporate Research             phone: 609-734-3347
>755 College Road East                  fax: 609-734-6565
>Princeton, NJ 08540

--
Paul T. Miller                | paul@elastic.avid.com
Principal Engineer            | Opinions expressed here are my own.
Avid Technology, Inc. Madison - Graphics and Effects Software Group
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: stephen.clamage_nospam@eng.sun.com (Steve Clamage)
Date: 1997/11/05
Raw View
On 04 Nov 97 05:15:28 GMT, mlg@scr.siemens.com (Michael Greenberg)
wrote:

>I believe the following is definitely incorrect.  (not that I think it
>should be).
>
>  class foo { } ;
>  class bar : public foo { } ;
>
>  ...
>
>  foo* f = new bar;
>  delete f;

The result of the code is formally undefined, and no diagnostic is
required. You can correctly delete an object via a pointer to a base
class only if the base class has a virtual destructor.

In the specific example with empty classes, the code would probably
run without a problem on most (if not all) implementations. You just
can't depend on it.

---
Steve Clamage, stephen.clamage_nospam@eng.sun.com
( Note: remove "_nospam" when replying )
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/11/05
Raw View
paul@ra.avid.com (Paul Miller) writes:

 >mlg@scr.siemens.com (Michael Greenberg) writes:
 >
 >>I believe the following is definitely incorrect.  (not that I think it
 >>should be).
 >
 >>  class foo { } ;
 >>  class bar : public foo { } ;
 >>
 >>  ...
 >
 >>  foo* f = new bar;
 >>  delete f;
 >
 >>Is my understanding correct?
 >
 >You do not need a virtual destructor (or a destructor at all)
 >if your class or any subclasses do not allocate any resources.

The draft standard says that you DO need a virtual destructor,
if you call delete with a static type that is different from the
dynamic type.  If you don't have one, the behaviour is undefined.
Undefined behaviour can of course include doing what you expect...

--
Fergus Henderson <fjh@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3         |     -- the last words of T. S. Garp.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: mlg@scr.siemens.com (Michael Greenberg)
Date: 1997/11/04
Raw View
I believe the following is definitely incorrect.  (not that I think it
should be).

  class foo { } ;
  class bar : public foo { } ;

  ...

  foo* f = new bar;
  delete f;

Is my understanding correct?

Thanks,


--
Michael Greenberg                      email: mgreenberg@scr.siemens.com
Siemens Corporate Research             phone: 609-734-3347
755 College Road East                  fax: 609-734-6565
Princeton, NJ 08540
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]