[comp.lang.c++] Delete-ing class hierarchie on free store

leo@atcmp.nl (Leo Willems) (04/22/89)

These are questions related to delete-ing inherited objects.

If there are two classes, X and Y, Y derived from X, (both with
destructors) the destructor Y::~Y() is -not- called in the next situation:

	X *x = new Y;		// ok: base pointer assignment
	delete x;		// only X::~X() called

Only the destructor for X is called.

There are a few things i want to know, the (syntactical) reason, and a way to
call all destructors.

1) problems i have with the reason (do i make the right assumptions??)

	If a -non virtual- base class function is called via a base class
	pointer, the base class function is used. Thus, since destructors
	are not virtual, the base class destructor is called.

	I feel this can not be (completely :-) correct since destructors
	are more than simple member functions: when using automatic
	storage, or casting:
		
		delete (Y*) x;

	the destructors are recursively called.

	What is the real story?

2)  (no real) solution:

	Use a cast ( as above).

	This re-introduces the type problem, for which inheritance
	was made for in the first place.


Solutions and explanations are welcome, please also tell me where i can find
these.

P.S.

	This problem occured when  i was playing with class filebuf:

	func()
	{
		{	
			filebuf fb(1);	// connect to stdout
		}
		// filebuf::~filebuf() called for fb.

		cout << "Nothing on stdout, ~filebuf() closed it!";
	}

	Is this standard behaviour(why) , a bug, redesigned in recent or future
	stream versions? It is easy to blame another but to me it's a bug:
	If I opened it, I want to close it, if ANOTHER opened it THEY should
	close it. 


If anything here is no, or an old problem please e-mail, thanks
for answers anyway.

Leo Willems
AT Computing
The Netherlands

Internet: leo@atcmp.nl
UUCP: mcvax!hp4nl!kunivv1!atcmpe!leo

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

In article <518@atcmpe.atcmp.nl>, leo@atcmp.nl (Leo  Willems) writes:

> If there are two classes, X and Y, Y derived from X, (both with
> destructors) the destructor Y::~Y() is -not- called in the next situation:

> 	X *x = new Y;		// ok: base pointer assignment
> 	delete x;		// only X::~X() called

> Only the destructor for X is called.

The situation shown above is invalid because x points at a Y,
not an X.  To get this to work properly, either you must write

	delete (Y*) x;

or X must have a virtual destructor.  The virtual destructor route
is recommended if you have any control over the definition of X.
-- 
				--Andrew Koenig
				  ark@europa.att.com