🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

4 total messages Started by Chris Parker Fri, 10 Nov 1995 05:24
Re: Virtual functions and destructors
#2493
Author: Chris Parker
Date: Fri, 10 Nov 1995 05:24
60 lines
3579 bytes
> > Is it acceptable according to the standard for the destructor to be the only
> > virtual member in the class?
> 
> Sure, but it's kind of pointless.  You only need a virtual destructor 
> when you will be handling objects of a derived class through a pointer or 
> reference whose static type is some base class, and in that case you will 
> (nearly?) always need other virtual functions to provide the polymorphic 
> interface that you'll use.  The only exception I can imagine offhand 
> would be if you were doing nothing but holding a bunch of them, as in a 
> collection of some sort; but how could you ever do anything to the 
> collected objects without virtual functions?  Seems to me that the only 
> thing you could do if they have no virtual function except the destructor 
> is delete them, and if that's all you're doing... well, I suppose there 
> could be some reason for deferring deletion for a bunch of mixed 
> objects.  It just doesn't seem real likely to me that that woudl be the 
> ONLY action you'd want to take on them in a polymorphic fashion.
> 
> But it's certainly legal to have only the destructor virtual.

You can do polymorphic things without any virtual functions.  Casting a child
to a parent which has no virtual functions makes the class behave like it was
a class of that parent.  You might want to delete it while it has been the
parent in a polymorphic sense.  Thus, the destructor is the only virtual 
function.  

> > Is virtualness inherited by destructors?  Does C++ automatically make all 
> > applicable superclasses also have virtual destructor if they don't already?
> 
> Is there any inheritance of anything from subclass to superclass?  Or did 
> you mean to write "subclass" there?  Inheritance goes in only one 
> direction: a class derived from a base class with a virtual destructor 
> will have a virtual destructor.  Deriving a class whose destructor is 
> declared virtual from a base class with a non-virtual destructor doesn't 
> magically change the base class in this respect (nor any other).

I did mean superclass when I said it.  Based on what I've learned by thinking
about these things, I'm pretty convinced that all destructors should be
virtual all the time (implied).  I can't find a single case where it would 
make sense to destroy an object and not have all proper cleanup happen.

> dispatch.  No magic, an object's actual type cannot affect anything done 
> to it through a pointer or reference of a base type unless the operation 
> is through a function that is virtual in that base type.

	The thing that doesn't work for me is that the pointer type is 
different, but it still has the same pointer value.  At the low-level, you
are freeing the same block of memory either way.  In order to 
call a destructor, the system needs to convert the pointer to a class type
instance anyway.

							Chris Parker
                                                        parker@cs.wpi.edu



---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: Virtual functions and destructors
#2498
Author: Herb Sutter
Date: Fri, 10 Nov 1995 19:30
27 lines
1862 bytes
In article <199511100139.UAA11974@starling.WPI.EDU>,
   Chris Parker <parker@owl.WPI.EDU> wrote:
>	The thing that doesn't work for me is that the pointer type is 
>different, but it still has the same pointer value.  At the low-level, you
>are freeing the same block of memory either way.  In order to 
>call a destructor, the system needs to convert the pointer to a class type
>instance anyway.

I don't follow.  To begin with, you certainly often do have different pointer 
values for the same object depending on which base pointer(s) you use to 
access it.  Simple example: Base classes B1 and B2, derived class D from both 
bases, and any D object will have a different pointer value when viewed 
through a B1* and a B2*; a B1* points to the "B1 part" of the derived object 
and a B2* points to the "B2 part" of the derived object.

If you fix that first sentence I think you'll see how to fix the rest too.


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Herb Sutter                 2228 Urwin, Ste 102         voice (416) 618-0184
Connected Object Solutions  Oakville ON Canada L6L 2T2    fax (905) 847-6019

---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: Virtual functions and destructors
#2543
Author: William Mooney
Date: Mon, 13 Nov 1995 18:09
62 lines
2853 bytes
John Max Skaller <maxtal@suphys.physics.su.oz.au> says:
>
>Chris Parker <parker@owl.WPI.EDU> wrote:
>>
>>I did mean superclass when I said it.  Based on what I've learned by thinking
>>about these things, I'm pretty convinced that all destructors should be
>>virtual all the time (implied).  I can't find a single case where it would 
>>make sense to destroy an object and not have all proper cleanup happen.
>
>Yes, but "safe cleanup" != "virtual destructor".
>In particular, a single stand alone class such 
>as "complex" doesn't need a virtual destructor
>because it is neither derived from nor is intended
>to be a base of, another class.
>
>Since on many systems virtual destructors
>greatly increase the costs associated
>with an object (size, dispatch efficiency, etc),
>there's a performance reason (as well as the
>obvious layout control reason) for not
>coding a virtual destructor in a class.
>
>{But I'm not disagreeing that in principle
>all destructors should act as if virtual}

Hmmm, this really sounds like a case of "do I plan for reuse now, or
wait until I need to reuse and then double check all of my parent
classes" -- both approaches have their merits.

What you can do if the cost of virtual destructors on standalone
classes concerns you, yet you or someone else *may* derive from them
at some point in time, is to wrap the virtual keyword like so:

class A
  {
  A();
  ...
#if defined(STRICT_VIRTUAL)
  virtual
#endif
  ~A();
  ...
  };

As ugly as using proprecessor symbols can be at least this gets around
around the problem.  Define STRICT_VIRTUAL in your header file before
including A.h and deriving from it.  Then #undef STRICT_VIRTUAL when
you're done to implement on a case-by-case basis.  Otherwise, put a 
-DSTRICT_VIRTUAL on the compiler command line for all cases.

Bill
=============================================================================
William D. Mooney       | email: wmooney@shl.com or 74353.1325@compuserve.com
                        | phone: 407.888.1829
SHL Systemhouse, Inc.   | fax:   407.888.2259
=============================================================================

---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: Virtual functions and destructors
#2564
Author: Stan Friesen
Date: Wed, 15 Nov 1995 16:47
67 lines
3562 bytes
In article <DHzpGF.DCt@shlnews.shl.com>, wmooney@shl.com (William Mooney) writes:
|> 
|> John Max Skaller <maxtal@suphys.physics.su.oz.au> says:
|> >Since on many systems virtual destructors
|> >greatly increase the costs associated
|> >with an object (size, dispatch efficiency, etc),
|> >there's a performance reason (as well as the
|> >obvious layout control reason) for not
|> >coding a virtual destructor in a class.
|> 
|> Hmmm, this really sounds like a case of "do I plan for reuse now, or
|> wait until I need to reuse and then double check all of my parent
|> classes" -- both approaches have their merits.

I would say it is "plan for reuse where it makes sense".

Some classes simply do not make sense in polymorphic usage.  In these
cases the class should be designed NOT to be derived from. Also, virtual
destructors are only needed if you are going to be deleting an object of
the class using a base class pointer - so add-on deriviation is still OK
as long as one never assigns the derived class to a base class pointer.

There are fundamentally three or four types of classes, each with different
requirements:

1. Stand-alone classes: these are classes that are complete in themselves,
			and for which deriviation is of doubtful significance.

2. Abstract classes:    these are classes that define an interface and a baseline
			implementation, but do not make sense as the type of
			an object.

3. Leaf classes:	these are classes that implement a concrete type based on
			an abstract interface.

and maybe
4. Mix-in classes:	these are classes that add features or capabilities to
			objects of other types.

Type 1 classes should have *no* virtual functions, and should never be
used as a public base class. Type 2 classes need at least one pure virtual
function, a virtual destructor, and maybe a set of basic algorithms. They
*must* be used as base classes.  Type 3 classes implement the virtual
functions defined in their base classes.

|> 
|> What you can do if the cost of virtual destructors on standalone
|> classes concerns you, yet you or someone else *may* derive from them
|> at some point in time, is to wrap the virtual keyword like so:

It is time to define classes as either usable as base classes or not.
And put this information in the *documentation*.  Then, since it is documented,
if somebody later derives from it, any problems are their fault.


Keep base classes distinct from stand-alone classes from the very beginning
of the design process.

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

The peace of God be with you.


[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads