Topic: Which delete operator should be called?
Author: brennan@hal.com (Dave Brennan)
Date: 3 Sep 92 07:08:54 GMT Raw View
It's not clear to me which delete operator should be called in the
following example program. The ARM says that the delete operator is
inherited, but is not virtual (which certainly makes since, because it
must be static).
All compilers that I testest this on indicated that the derived delete
operator is called when the destructor is virtual. If the destructor is
non-virtual the base class delete operator is called. So at least in some
compilers the delete operator IS virtual if the destructor is. This may be
reasonable behavior but seems contrary to what the ARM says.
Somewhat related to this, I need to be able to call the virtual destructor
of an object without deleting it. I can't get any compilers to accept any
destructor calling syntax other than "class::~class()" (where "class" is a
class name). In cfront this syntax DOES call the virtual destructor (ie:
if I call "base::~base()" from a base method, the derived destructor is
called). Lucid CC it only called the base class destructor, which seems
like the correct behavior. g++ 2.2.2 wouldn't accept any kind of explicit
calls to a destructor. Can anyone tell me how to call a virtual destructor
in a way that least cfront 2.1 will accept and is correct C++?
extern "C" void puts (char *);
class base
{
public:
virtual ~base ()
{ puts ("destruct base"); }
void operator delete (void *)
{ puts ("delete base"); }
void destruct ()
{ base::~base (); }
};
class derived : public base
{
public:
~derived ()
{ puts ("destruct derived"); }
void operator delete (void *)
{ puts ("delete derived"); }
};
int
main ()
{
base *b = new derived;
delete b;
}
--
Dave Brennan HaL Computer Systems
brennan@hal.com (512) 794-2855
Visit the Emacs Lisp Archive: archive.cis.ohio-state.edu:pub/gnu/emacs
Author: adk@Warren.MENTORG.COM (Ajay Kamdar)
Date: Thu, 3 Sep 1992 17:11:47 GMT Raw View
In article <BRENNAN.92Sep3010854@yosemite.hal.com> brennan@hal.com (Dave Brennan) writes:
>Somewhat related to this, I need to be able to call the virtual destructor
>of an object without deleting it. I can't get any compilers to accept any
>destructor calling syntax other than "class::~class()" (where "class" is a
>class name). In cfront this syntax DOES call the virtual destructor (ie:
>if I call "base::~base()" from a base method, the derived destructor is
>called). Lucid CC it only called the base class destructor, which seems
>like the correct behavior. g++ 2.2.2 wouldn't accept any kind of explicit
>calls to a destructor. Can anyone tell me how to call a virtual destructor
>in a way that least cfront 2.1 will accept and is correct C++?
>
#include <iostream.h>
class A {
public:
A() {}
virtual ~A() {cout << "A's dtor" << endl;}
virtual void callDtorInPlace() {this->A::~A();}
// legal code. Will work in both 2.1 and 3.0
// virtual void callDtorInPlace() {this->~A();}
// legal code, but doesn't work in 2.1.
// Works ok in 3.0
// virtual void callDtorInPlace() {A::~A();}
// This is illegal, but works under 2.1.
// 3.0 compiles this, but doesn't produce any output.
};
class B : public A {
public:
B() {}
~B() {cout << "B's dtor" << endl;}
void callDtorInPlace() {this->B::~B();}
// legal code. works with both 2.1 and 3.0
// void callDtorInPlace() {this->~B();}
// legal code which does not work with 2.1. Works ok with 3.0
// virtual void callDtorInPlace() {B::~B();}
// illegal code which works with 2.1
};
main()
{
A *a = new B();
a->callDtorInPlace();
}
--
I speak for none but myself.
Ajay Kamdar Email : ajay_kamdar@mentorg.com
Mentor Graphics, IC Group (Warren, NJ) Phone : (908) 580-0102
Author: brennan@hal.com (Dave Brennan)
Date: 3 Sep 92 15:53:03 GMT Raw View
I didn't have my copy of ARM handy when I posted, and I see that it also
says is 12.4 (p. 278) "When invoked by the delete operator, memory is freed
by the destructor for the most derived class of the object using an
operator delete ()."
What it doesn't say is which operator delete. This tends to imply that the
operator delete of the most derived class should be used, but as my
previous post showed it is only used when the class being deleted has a
virtual destructor. This quote implies that the operator delete of the
most derived class will be called when any object is deleted?
Cany anyone clarify this?
--
Dave Brennan HaL Computer Systems
brennan@hal.com (512) 794-2855
Visit the Emacs Lisp Archive: archive.cis.ohio-state.edu:pub/gnu/emacs
Author: pete@genghis.borland.com (Pete Becker)
Date: Thu, 3 Sep 1992 18:22:46 GMT Raw View
In article <BRENNAN.92Sep3095303@yosemite.hal.com> brennan@hal.com (Dave Brennan) writes:
>I didn't have my copy of ARM handy when I posted, and I see that it also
>says is 12.4 (p. 278) "When invoked by the delete operator, memory is freed
>by the destructor for the most derived class of the object using an
>operator delete ()."
>
>What it doesn't say is which operator delete. This tends to imply that the
>operator delete of the most derived class should be used, but as my
>previous post showed it is only used when the class being deleted has a
>virtual destructor. This quote implies that the operator delete of the
>most derived class will be called when any object is deleted?
>
>Cany anyone clarify this?
>
Don't make this problem harder than it really is. Destructors and
operator delete aren't magic. Just rephrase the question in terms of normal
functions:
class Base
{
public:
static void operation();
void f() { operation(); }
virtual void g() { operation(); }
};
class Derived : public Base
{
public:
static void operation();
void f() { operation(); }
virtual void g() { operation(); }
};
Base *bp = new Derived;
bp->f(); // invokes Base::f(), which calls Base::operation()
bp->g(); // invokes Derived::g(), which calls
// Derived::operation()