[comp.lang.c++] do destructors descend hierarchy?

rpj@redcloud.cad.mcc.com (Rich Johns) (07/03/89)

Assume the class Blue, which is a PrimaryColor, which is a Color.  All three classes
have destructors. If I have a Blue b allocated from free store:

   Blue* b = new Blue;

Now if I:

   delete b;

will the destructors for PrimaryColor and Color be called?


  

 
 
 
Rich Johns, MCC CAD Program | 3500 W. Balcones Center Dr., Austin, TX 78759
ARPA: johns@mcc.com         | Phone: [512] 338-3714
UUCP: {uunet,harvard,gatech,pyramid}!cs.utexas.edu!milano!cadillac!johns

ark@alice.UUCP (Andrew Koenig) (07/04/89)

In article <1570@cadillac.CAD.MCC.COM>, rpj@redcloud.cad.mcc.com (Rich Johns) writes:

> Assume the class Blue, which is a PrimaryColor, which is a Color.  All three classes
> have destructors. If I have a Blue b allocated from free store:

>    Blue* b = new Blue;

In other words, your declarations look like this:

	class Color { /* stuff */ };
	class PrimaryColor: public Color { /* more stuff */ };
	class Blue: public PrimaryColor { /* still more stuff */ };

> Now if I:

>    delete b;

> will the destructors for PrimaryColor and Color be called?

Yes.

More specifically, when you said `new Blue,' that caused the
constructors for Color, PrimaryColor, and Blue to be executed
in that order.  When you say `delete b,' it causes the destructors
for Blue, PrimaryColor, and Color to be executed in that order.
-- 
				--Andrew Koenig
				  ark@europa.att.com

sakkinen@tukki.jyu.fi (Markku Sakkinen) (07/05/89)

In article <9555@alice.UUCP> ark@alice.UUCP (Andrew Koenig) writes:
-In article <1570@cadillac.CAD.MCC.COM>, rpj@redcloud.cad.mcc.com (Rich Johns) writes:
-
-> Assume the class Blue, which is a PrimaryColor, which is a Color.  All three classes
-> have destructors. If I have a Blue b allocated from free store:
-
->    Blue* b = new Blue;
-
-In other words, your declarations look like this:
-
-	class Color { /* stuff */ };
-	class PrimaryColor: public Color { /* more stuff */ };
-	class Blue: public PrimaryColor { /* still more stuff */ };
-
-> Now if I:
-
->    delete b;
-
-> will the destructors for PrimaryColor and Color be called?
-
-Yes.
-
-More specifically, when you said `new Blue,' that caused the
-constructors for Color, PrimaryColor, and Blue to be executed
-in that order.  When you say `delete b,' it causes the destructors
-for Blue, PrimaryColor, and Color to be executed in that order.
--- 
-				--Andrew Koenig
-				  ark@europa.att.com

Please, remember that you are using C++ release 2.0 yourself
but we others outside Bell Labs have not got it (at least yet)!
The sad fact about earlier AT&T releases is that if there is
an assignment to the variable this in a constructor (destructor)
of a derived class, the constructor (destructor) of its base class
will never be called. I don't know about those C++ compilers
(Oregon Software, Zortech, GNU, others?) that are not based on
AT&T's product.

As shown in my paper at ECOOP'88, the whole idea of assigning
to "this" in constructors and destructors causes a mess.
Fortunately it seems to get replaced by an orderly possibility
to overload the operators new and delete in release 2.0.

Markku Sakkinen
Department of Computer Science
University of Jyvaskyla (a's with umlauts)
Seminaarinkatu 15
SF-40100 Jyvaskyla (umlauts again)
Finland

lpringle@bbn.com (Lewis G. Pringle) (07/06/89)

In article <9555@alice.UUCP> ark@alice.UUCP (Andrew Koenig) writes:
>>    Blue* b = new Blue;
>
>In other words, your declarations look like this:
>
>	class Color { /* stuff */ };
>	class PrimaryColor: public Color { /* more stuff */ };
>	class Blue: public PrimaryColor { /* still more stuff */ };
>
>> Now if I:
>
>>    delete b;
>
>> will the destructors for PrimaryColor and Color be called?
>
>Yes.

This brings up an anoying point about c++.  The above works correctly as
Andrew points out, but the following:
	Color* b = new Blue;

	delete b;

Fails in a very bizzare and subtle way.  The trouble is that the DTOR was
not declared virtual (actually in the example above, the author failed to
specify whether or not the dtor was virtual).

Is there any rationalle at all (beyond a slight effecicy issue in case of
classes with dtors not derived from) for not making dtors always virtual?
For sake of symetry with the behavior of ctors it seems quite natural.
I expect that a common c++ bug is to ASSUME the dtor of the DYNAMIC class
is called when in reallity, only the STATIC type (pointer base type) dtor
is used.

				Lewis.



"OS/2: half an operating system for half a computer."

In Real Life:		Lewis Gordon Pringle Jr.
Electronic Mail:	lpringle@labs-n.bbn.com
Phone:			(617) 873-4433

ark@alice.UUCP (Andrew Koenig) (07/06/89)

In article <42280@bbn.COM>, lpringle@bbn.com (Lewis G. Pringle) writes:

> Is there any rationale at all (beyond a slight effecicy issue in case of
> classes with dtors not derived from) for not making dtors always virtual?

No, but the efficiency issue is not always slight.

For example, if the class has no virtual functions aside from
the destructor, making the destructor virtual will cause the class
to acquire a (hidden) pointer to a virtual table.  If the class
itself is very small, this pointer may be a significant
fraction of the space occupied by an object, which in turn may
make a difference if you have zillions of objects.

Such matters can be important in things like string classes.
Note also that you can often effectively add a virtual destructor to
a class that doesn't have one by deriving a class of your own
that has a virtual destructor and nothing else.
-- 
				--Andrew Koenig
				  ark@europa.att.com