|
|||||
|
|
#1 |
|
|
virtual destructor when someone says delete using a Base pointer that's pointing at a Derived object. When you say delete p, and the cl*** of p has a virtual destructor, the destructor that gets invoked is the one ***ociated with the type of the object *p, not necessarily the one ***ociated with the type of the pointer. This is A Good Thing. In fact, violating that rule makes your program undefined." What's "the cl*** of p", Base cl***? What's "the type of the object *p", Base or Derived? "the destructor that gets invoked is..." Both destructors in Base AND Derived are invoked. Why only one is mentioned here? Thanks in advance! |
|
|
#2 |
|
|
> In C++ FAQ 20.5, "...here are the mechanical details of why you need a > virtual destructor when someone says delete using a Base pointer that's > pointing at a Derived object. When you say delete p, and the cl*** of p has > a virtual destructor, the destructor that gets invoked is the one ***ociated > with the type of the object *p, not necessarily the one ***ociated with the > type of the pointer. This is A Good Thing. In fact, violating that rule > makes your program undefined." > > What's "the cl*** of p", Base cl***? Yes. > What's "the type of the object *p", Base or Derived? The same as above, Base. The FAQ could need a little rewording here, yes. > "the destructor that gets invoked is..." > Both destructors in Base AND Derived are invoked. Why only one is mentioned > here? Both are invoked if the one in Base is virtual. Otherwise only the one in Base is invoked. The reason only one is mentioned is because only the one that is directly invoked by the delete expression is relevant. When the one in Derived is directly invoked (as can happen when you have a Derived* pointer) it doesn't matter whether the Base destructor is virtual or not, because the Derived destructor knows that Derived is derived from Base, and invokes the Base destructor automagically. When the one in Base is the one directly invoked, as happens when the pointer is a Base* and the destructor in Base is non-virtual, it doesn't know anything about any Derived object needing destruction. So nothing more happens. -- A: Because it messes up the order in which people normally read text. Q: Why is it such a bad thing? A: Top-posting. Q: What is the most annoying thing on usenet and in e-mail? |
|
|
#3 |
|
|
> * ctick: > > In C++ FAQ 20.5, "...here are the mechanical details of why you need a > > virtual destructor when someone says delete using a Base pointer that's > > pointing at a Derived object. When you say delete p, and the cl*** of p has > > a virtual destructor, the destructor that gets invoked is the one ***ociated > > with the type of the object *p, not necessarily the one ***ociated with the > > type of the pointer. This is A Good Thing. In fact, violating that rule > > makes your program undefined." > > > > What's "the cl*** of p", Base cl***? > > Yes. > > > > What's "the type of the object *p", Base or Derived? > > The same as above, Base. Oops, I meant of course Derived. *p is the object that p points to. Which in this case is a Derived object. > The FAQ could need a little rewording here, yes. Absolutely! ;-) > > "the destructor that gets invoked is..." > > Both destructors in Base AND Derived are invoked. Why only one is mentioned > > here? > > Both are invoked if the one in Base is virtual. > > Otherwise only the one in Base is invoked. > > The reason only one is mentioned is because only the one that is > directly invoked by the delete expression is relevant. When the one in > Derived is directly invoked (as can happen when you have a Derived* > pointer) it doesn't matter whether the Base destructor is virtual or > not, because the Derived destructor knows that Derived is derived from > Base, and invokes the Base destructor automagically. When the one in > Base is the one directly invoked, as happens when the pointer is a Base* > and the destructor in Base is non-virtual, it doesn't know anything > about any Derived object needing destruction. So nothing more happens. > > -- > A: Because it messes up the order in which people normally read text. > Q: Why is it such a bad thing? > A: Top-posting. > Q: What is the most annoying thing on usenet and in e-mail? -- A: Because it messes up the order in which people normally read text. Q: Why is it such a bad thing? A: Top-posting. Q: What is the most annoying thing on usenet and in e-mail? |
|
|
#4 |
|
|
ctick wrote:
> In C++ FAQ 20.5, "...here are the mechanical details > of why you need a virtual destructor when someone says delete > using a Base pointer that's pointing at a Derived object. > When you say delete p, and the cl*** of p has a virtual destructor, > the destructor that gets invoked > is the one ***ociated with the type of the object *p, > not necessarily the one ***ociated with the type of the pointer. > This is A Good Thing. > In fact, violating that rule makes your program undefined." This is bad advice and typical of the muddled thinking that p***es for "object oriented programming" these days. > > What's "the cl*** of p", Base cl***? Pointer p is a pointer to an object of the Base type. > What's "the type of the object *p", Base or Derived? Reference *p is a reference to an object of the Base type. What the author means is that p was converted from a pointer to an object of the Derived type to a pointer to an object of the Base type. Invocation of a virtual function for the Base type will actually invoke the corresponding function defined for the Derived type. > > "the destructor that gets invoked is..." > Both destructors in Base AND Derived are invoked. > Why only one is mentioned here? The author was simply careless. Evidently, the author believes that, when programmers write delete p; they mean to delete an object of the Derived type if p was actually converted from a pointer to an object of a Derived type. This is a *very* weak argument for a *virtual* destructor. The Base cl*** could have defined a virtual member function: void Base::free(void) const { delete this; } to accompany a "virtual constructor" member function: Base* Base::allocate(void) { return new Base; } The problem here is that so-called "object oriented programmers" are attempting to mimic Java programmers. But C++ is *not* Java. Java has a built-in garbage collector to clean up dangling references so that Java programmers needn't worry about memory leaks. |
|
|
#5 |
|
|
ctick posted:
> In C++ FAQ 20.5, "...here are the mechanical details of why you need a > virtual destructor when someone says delete using a Base pointer that's > pointing at a Derived object. When you say delete p, and the cl*** of p > has a virtual destructor, the destructor that gets invoked is the one > ***ociated with the type of the object *p, not necessarily the one > ***ociated with the type of the pointer. This is A Good Thing. In fact, > violating that rule makes your program undefined." > > What's "the cl*** of p", Base cl***? > > What's "the type of the object *p", Base or Derived? > > "the destructor that gets invoked is..." > Both destructors in Base AND Derived are invoked. Why only one is > mentioned here? > > Thanks in advance! Imagine the following: When a mammal, dies it exhales. A dog is a mammal. Therefore when it dies it exhales. But my dog also barks too when it dies. Here we go: cl*** Mammal { public: ~Mammal(void) { Exhale(); } }; cl*** Dog : public Mammal { public: ~Dog(void) { Bark(); } }; int main(void) { Dog* Sparky = new Dog; delete Sparky; //Here, it barks, then it dies //Now imagine that this is a wildlife centre for mammals. They'd don't //care whether it's a dog or cat or monkey or rhino... they just care //that it's a mammal. Take the following: Mammal* Sparky2 = new Dog; delete Sparky2; //Here, it DOESN'T bark before it dies. //If Mammal had had a virtual destructor, then Yes, it would have //barked before it died! } |
|
|
#6 |
|
|
"E. Robert Tisdale" <E.Robert.Tisdale@jpl.nasa.gov> wrote in message
news:cb2909$i8a$1@nntp1.jpl.nasa.gov > ctick wrote: > >> In C++ FAQ 20.5, "...here are the mechanical details >> of why you need a virtual destructor when someone says delete >> using a Base pointer that's pointing at a Derived object. >> When you say delete p, and the cl*** of p has a virtual destructor, >> the destructor that gets invoked >> is the one ***ociated with the type of the object *p, >> not necessarily the one ***ociated with the type of the pointer. >> This is A Good Thing. >> In fact, violating that rule makes your program undefined." > > This is bad advice and typical of the muddled thinking > that p***es for "object oriented programming" these days. >> >> What's "the cl*** of p", Base cl***? > > Pointer p is a pointer to an object of the Base type. > >> What's "the type of the object *p", Base or Derived? > > Reference *p is a reference to an object of the Base type. > What the author means is that > p was converted from a pointer to an object of the Derived type > to a pointer to an object of the Base type. > Invocation of a virtual function for the Base type > will actually invoke the corresponding function > defined for the Derived type. >> >> "the destructor that gets invoked is..." >> Both destructors in Base AND Derived are invoked. >> Why only one is mentioned here? > > The author was simply careless. > Evidently, the author believes that, > when programmers write > > delete p; > > they mean to delete an object of the Derived type > if p was actually converted from a pointer > to an object of a Derived type. > > This is a *very* weak argument for a *virtual* destructor. > The Base cl*** could have defined a virtual member function: > > void Base::free(void) const { > delete this; > } > > to accompany a "virtual constructor" member function: > > Base* Base::allocate(void) { > return new Base; > } > > The problem here is that so-called "object oriented programmers" > are attempting to mimic Java programmers. But C++ is *not* Java. > Java has a built-in garbage collector to clean up dangling references > so that Java programmers needn't worry about memory leaks. I wonder what language you are trying to program in or whether you read the full text of this particular FAQ. The FAQ refers to a situation in which Base pointers may point to Derived objects, presumably in order to achieve polymorphic behaviour. The programmer calls delete on these Base pointers without knowing --- and without wanting to know --- the kind of object that is pointed to. Making the destructors virtual ensures that the correct destructor(s) will be called. This is a simple and elegant procedure. -- John Carson 1. To reply to email address, remove donald 2. Don't reply to email address (post here instead) |
|
|
#7 |
|
|
John Carson wrote:
> I wonder what language you are trying to program in > or whether you read the full text of this particular FAQ. > The FAQ refers to a situation > in which Base pointers may point to Derived objects, > presumably in order to achieve polymorphic behaviour. > The programmer calls delete on these Base pointers > without knowing --- and without wanting to know --- > the kind of object that is pointed to. > Making the destructors virtual ensures that > the correct destructor(s) will be called. > This is a simple and elegant procedure. It is an elegant procedure in *Java*. In C++, it is a souce of memory leaks. |
|
|
#8 |
|
|
"E. Robert Tisdale" <E.Robert.Tisdale@jpl.nasa.gov> wrote in message news:cb37ue$3m6$1@nntp1.jpl.nasa.gov... > John Carson wrote: > > > I wonder what language you are trying to program in > > or whether you read the full text of this particular FAQ. > > The FAQ refers to a situation > > in which Base pointers may point to Derived objects, > > presumably in order to achieve polymorphic behaviour. > > The programmer calls delete on these Base pointers > > without knowing --- and without wanting to know --- > > the kind of object that is pointed to. > > Making the destructors virtual ensures that > > the correct destructor(s) will be called. > > This is a simple and elegant procedure. > > It is an elegant procedure in *Java*. > In C++, it is a souce of memory leaks. How so? john |
|
|
#9 |
|
|
"E. Robert Tisdale" <E.Robert.Tisdale@jpl.nasa.gov> wrote in message
news:cb37ue$3m6$1@nntp1.jpl.nasa.gov > John Carson wrote: > >> I wonder what language you are trying to program in >> or whether you read the full text of this particular FAQ. >> The FAQ refers to a situation >> in which Base pointers may point to Derived objects, >> presumably in order to achieve polymorphic behaviour. >> The programmer calls delete on these Base pointers >> without knowing --- and without wanting to know --- >> the kind of object that is pointed to. >> Making the destructors virtual ensures that >> the correct destructor(s) will be called. >> This is a simple and elegant procedure. > > It is an elegant procedure in *Java*. > In C++, it is a souce of memory leaks. If you are referring to the manual calling of delete and hence the possibility that the programmer may forget to call it, then this can be handled by the use of smart pointers. The destructor must still be virtual. -- John Carson 1. To reply to email address, remove donald 2. Don't reply to email address (post here instead) |