Topic: Virtual destructors: required always? (long)


Author: rfg@netcom.com (Ronald F. Guilmette)
Date: Mon, 1 Nov 1993 09:39:46 GMT
Raw View
In article <CBARBER.93Oct21111816@apricot-fddi.bbn.com> cbarber@bbn.com (Christopher Barber) writes:
>In article <rfgCF7D8n.12z@netcom.com> rfg@netcom.com
>(Ronald F. Guilmette) writes:
>
>   In article <CBARBER.93Oct19111943@apricot-fddi.bbn.com>
>        cbarber@apricot-fddi.bbn.com (Chris Barber) writes:
>
>   >In article <rfgCF3u3K.3Dr@netcom.com> rfg@netcom.com
>   >(Ronald F. Guilmette) writes:
>   >
>   >   In article <26917@alice.att.com> ark@alice.UUCP (Andrew Koenig) writes:
>   >   >The `virtuality' of destructors is inherited.
>   >
>   >This rule is implied by the definition of virtual functions.
>                 ^^^^^^^
>...
>   This is generally understood to mean that if a base class declares a
>   function WITH A GIVEN NAME as virtual, and if a class derived from that
>   class also declares a function WITH THAT EXACT SAME NAME AND SIGNATURE
>   then the one in the derived class is also (implicitly) virtual, whether
>   or not one declares it as such.
>
>   I emphasize that the two function must have THE SAME NAME in both the
>   base and derived classes.  Thus, the rule you have quoted clearly does
>   not apply to destructors.
>
>Well, I suppose one could read it that way.  But the text does not
>actually say that the functions must have the same textual tag or
>name, although it is hard to interpret it any other way for anything
>except destructors.

It is hard to interpret it any other way period.

>   Also perfectly clear???  What was the first thing that was perfectly
>   clear???
>...
>Ok.  Here is the commentary from 12.4 (p.277-8):
>
>  It is often a good idea to declare a destructor virtual.  If a
>  destructor is not virtual one can get caught in this mess:
>
>     class B {
>       // ...
>     public:
>       B() ;
>       ~B() ;
>     } ;
>
>     class D : public B {
>       // ....
>     public:
>       D() ;
>       ~D() ;
>     } ;
>
>     void f()
>     {
>        B* p = new D();   // create a D
>        delete p ;        // delete a B
>     }
>
>  Since B's destructor was not virtual, the delete statement calls B::~B()
>  and not D::~D() as was presumably needed for correct operation.
>  Declaring B::~B() 'virtual' solves the problem.
>
>     class B {
>        // ...
>        B() ;
>        virtual ~B() ;
>     } ;
>
>Note that their solution is to make ~B() virtual *not* ~D().  This solution
>clearly indicates that declaring ~B() virtual will make ~D() virtual...

It clearly indicates that does it?  Well, I guess I'm just a dunce, but
I don't see where it clearly indicates that.  All is says is that making
B::~B() virtual "solves the problem".  It never says how, nor does it
even give any blatant clues.

>Maybe you are right.  Anyway, although I do think that the intent
>is fairly clear from the ARM, I think that your arguments make a
>strong case for putting something more explicit in the standard.
>After all, what could it hurt?

Right.  My point exactly.  I think if we who write C++ code should have
learned anything over the past few years, it is that implementors are
capable of displaying vast amounts of creativity and inventiveness (but
always in divergent directions) when it comes to interpreting things that
many of us would claim were "obvious" from reading the ARM.

--

-- Ronald F. Guilmette, Sunnyvale, California -------------------------------
------ domain address: rfg@netcom.com ---------------------------------------
------ uucp address: ...!uunet!netcom.com!rfg -------------------------------