Re: Virtual destructors are unique virtuals right

From: Howard (alicebt_at_hotmail.com)
Date: 03/24/04


Date: 24 Mar 2004 10:46:22 EST


"Siemel Naran" <SiemelNaran@REMOVE.att.net> wrote in message
news:hZc8c.13360$tY6.381457@bgtnsc04-news.ops.worldnet.att.net...
> "Howard" <alicebt@hotmail.com> wrote in message
> news:c3qh26$qnu@dispatch.concentric.net...
> > "John Cho" <johncho@johncho.us> wrote in message
>
> > > if i make a virtual function it is so the dervive function gets
called
> > >
> > > and it is very different because the virtual destructor calls the
> > > dervive
> > > and then base
> > >
> > > whereas regular virtual functions call the dervive function and not
the
> > > base function at all huh.
>
> Right. It is a difference. However a lot but not all of the virtual
> functions we implement will call the base class function then do some
> additional processing (or do some additional processing then call the base
> class virtual function). However, the language does not require this.
Only
> our business logic does.
>
>
> > Not exactly. The destructor of a derived class does not call the
> destructor
> > of its base class, regardless of whether the base class has a virtual
> > destructor.
>
> I disagree. The derived class destructor always calls the base class
> destructor.
>

Destructors do not call other destructors. The compler generates code to
call them in the reverse order in which their constructors were called.

>
> > The destructor of an object is called when that object is deconstructed,
> in
> > the opposite order in which it was constrcuted. In general, the derived
> > calls will get destroyed, calling its destructor, then the next most
base
> > class (ancestor) gets destroyed, calling its destructor, etc. This
> happens
> > regardless of whether the destrucotr of any base class is virtual or
not.
>
> Right, the derived class destructor always calls the base class
destructor.
> It seems your two paragraphs contradict each other. My language problem?
>

The only language difficulty I see may be my use of the term "deconstructed"
above. You're just mistaken on what calls whom. What happens is that, when
you call new, the compiler generates a call to operator new, as in:

BaseClass::operator new(sizeof(DerivedClass));

The compiler creates anough memory for the derived object, then calls the
constructor for the BaseClass, then calls the constructor for the
DerivedClass. One constructor does not call another.

The reverse order is used for deconstructing: The compiler calls the
destructor for the DerivedClass, then the destructor for the BaseClass, and
then deletes the memory, using operator delete.

(There is also construction and destruction for class members thrown in
there, but that's not relevant to this issue.)

>
> > The purpose of the virtual destructor is so that, if you instantiate an
> > object via new, and assign that instance to a type
> > "pointer-to-some-base-class", then the delete operator will know what
size
> > will need to be passed when freeing up the memory for the derived class.
>
> I disagree. The virtual destructor ensures that the derived class virtual
> destructor gets called, thereby resources associated with the derived-only
> portion of the class get released. As for the size, your statement below
> may be correct depending on the implementation, but in many
implementations
> the actual size of the object is known in any case because when you say
> void * v = new DerivedObject();
> the memory manager stores the size of DerivedObject along with 'v' (maybe
> just before 'v' or in a seperate memory map). So in this implementation
> delete v always deletes the memory directly held by DerivedObject.
Casting
> to Object *, using a virtual destructor, etc, just ensures the proper
> destructor gets called. This is important if the class has member
variables
> that manage dynamic memory like std::string and std::vector; so that we
call
> the destructor for each of these member variable objects.
>

Calling delete v in your example above will give you undefined behavior.
The object being deleted (via delete) must be of the same type that was
allocated via new, or a base class of that type. (That's in the standard.)
No destructor could possibly be called (or even operator delete) for a void
pointer, since there is no class to associate with.

-Howard



Relevant Pages

  • Re: Odd behavior, vector member, MFC and consol app
    ... someone call the base class destructor which then ended up doing something bad. ... it should have no virtual functions at all. ... A good clue that a class is not intended for derivation is the absence ...
    (microsoft.public.vc.mfc)
  • Re: Cant compile this code *****SOLVED****
    ... your real program might contain hundreds of code sequences ... that the base class implements a 'virtual' ... destructor, so that when de-allocating objects created via ...
    (alt.comp.lang.learn.c-cpp)
  • Re: inhibit compiler warning C4624 for a class hierarchy
    ... Any class must have a destructor before you can ... create (or, to be exact, destroy) an instance of it. ... implicitly-declared destructor, ... a base class with an inaccessible destructor. ...
    (microsoft.public.vc.language)
  • Re: My final shape program, what do you think?
    ... >> pointer to its base class then the base class must have a virtual ... >> destructor or its undefined behaviour. ... > i should have to use a virtual deconstructor if i want dervive ...
    (alt.comp.lang.learn.c-cpp)
  • Re: My final shape program, what do you think?
    ... >> pointer to its base class then the base class must have a virtual ... >> destructor or its undefined behaviour. ... > i should have to use a virtual deconstructor if i want dervive ...
    (comp.lang.cpp)