|
|||||
|
|
#1 |
|
|
sure the destructor of Derived cl*** will be invoked when a pointer of Base type is used to delete an object of Derived. Is this the only reason to define "virtual destructor" for a Base cl***? Since it's always possible that users of any Base cl*** will delete a Derived object like that, does this mean that a "virtual destructor" is always necessary? Thanks in advance! |
|
|
#2 |
|
|
> A reason for declaring a "virtual destructor" for a Base cl*** is to make > sure the destructor of Derived cl*** will be invoked when a pointer of Base > type is used to delete an object of Derived. > > Is this the only reason to define "virtual destructor" for a Base cl***? > > Since it's always possible that users of any Base cl*** will delete a > Derived object like that, does this mean that a "virtual destructor" is > always necessary? > > Thanks in advance! Make all destructors virtual unless profiling reveals you really really really don't need one. If your cl*** is abstract, with only pure virtual methods, make the destructor pure virtual too. Only one sequence of events leads to undefined behavior: A base cl*** has no virtual destructor, you derive from it, create a 'new' derived object, take this object's address, convert the address to the base type, and 'delete'. 'delete'ing a base type pointer is not a rare sequence of events in wildly polymorphic designs. You should take greater care to ensure that the return value of 'new' is always stored in a smart pointer or equivalent of the correct derived type, so destruction becomes automatic. And plenty of polymorphic designs use only the stack to store objects, so all these situations destroy and clean up correctly. However, refactors and new features could easily migrate a statically allocated object into a dynamic one. At this time, nothing in your system will tell you if your 'delete' creates undefined behavior (except possibly a lint tool). The language permits this loophole to permit tuning performance. Sometimes the tiny overhead of a virtual method table hurts, so you can always take it out. A keyword called "unvirtual" would be silly, so you must simply always make destructors virtual. -- Phlip http://industrialxp.org/community/bi...UserInterfaces |
|
|
#3 |
|
|
"ctick" <ctick@flare.com> wrote in message news:bZ8Bc.7621$OB3.2639@bgtnsc05-news.ops.worldnet.att.net... > A reason for declaring a "virtual destructor" for a Base cl*** is to make > sure the destructor of Derived cl*** will be invoked when a pointer of Base > type is used to delete an object of Derived. > > Is this the only reason to define "virtual destructor" for a Base cl***? Pretty much yes. There is one other rather obscure reason. It might be that you want cl*** Base to have at least one virtual function (so that you can use dynamic_cast on it for instance) but you don't have any other suitable method to declare as virtual. > > Since it's always possible that users of any Base cl*** will delete a > Derived object like that, does this mean that a "virtual destructor" is > always necessary? Not really. There is an overhead to using virtual functions. If your cl*** is not intended to be used polymorphically then don't use any virtual functions (including destructor) and do***ent that fact. Unfortunately its always possible that users will do something stupid. john |
|
|
#4 |
|
|
Phlip wrote:
> ctick wrote: > >>A reason for declaring a "virtual destructor" for a Base cl*** >>is to make sure the destructor of Derived cl*** will be invoked >>when a pointer of Base type is used to delete an object of Derived. >> >>Is this the only reason to define "virtual destructor" for a Base cl***? >> >>Since it's always possible that users of any Base cl*** >>will delete a Derived object like that, does this mean that >>a "virtual destructor" is always necessary? > > Make all destructors virtual > unless profiling reveals you really really really don't need one. This is *very* bad advice. If all C++ destuctors were meant to be virtual, that feature would have been built into the language -- or the language would have been renamed Java. |
|
|
#5 |
|
|
John Harrison wrote:
> There is an overhead to using virtual functions. cl*** Base { public: virtual ~Base(void) { } }; cl*** Derived: public Base { public: virtual ~Derived(void) { } }; void blackHole(Base* p) { delete [] p; } Derived* p = new Derived[bzillion]; blackHole(p); The destructors do nothing and a good C++ compiler could have optimized them away if they weren't virtual destructors but, because the destuctor for the base cl*** was declared virtual, the compiler will be forced to emit code to call the destructor for Derived a bzillion times -- to do nothing! > If your cl*** is not intended to be used polymorphically, > then don't use any virtual functions (including destructor) > and do***ent that fact. Even if your cl*** *is* intended to be used polymorphically, you really need a strong argument to include a virtual destructor. |
|
|
#6 |
|
|
On Sat, 19 Jun 2004 22:51:01 -0700 in comp.lang.c++, "E. Robert Tisdale"
<E.Robert.Tisdale@jpl.nasa.gov> wrote, > >This is *very* bad advice. >If all C++ destuctors were meant to be virtual, >that feature would have been built into the language -- >or the language would have been renamed Java. Come on, Robert, you know it's only very ordinary everyday grade bad advice. Sure it will make your programs slower and eat a bit more memory for no good reason, but I can't think of a case where it will make them give wrong answers or undefined behavior. And it might even save somebody's clueless butt, once in a blue moon. I told you a million times not to exaggerate. |
|
|
#7 |
|
|
"David Harmon" <source@netcom.com.invalid> wrote in message
news:40ec3bb0.36396009@news.west.earthlink.net > > I told you a > million times not to exaggerate. ![]() -- John Carson 1. To reply to email address, remove donald 2. Don't reply to email address (post here instead) |
|
|
#8 |
|
|
ctick posted:
> A reason for declaring a "virtual destructor" for a Base cl*** is to > make sure the destructor of Derived cl*** will be invoked when a > pointer of Base type is used to delete an object of Derived. > > Is this the only reason to define "virtual destructor" for a Base > cl***? > > Since it's always possible that users of any Base cl*** will delete a > Derived object like that, does this mean that a "virtual destructor" is > always necessary? > > Thanks in advance! Write your program. At the end, analyse it and see if you use a pointer of type Base* to delete an object of type Derived . If so, declare ~Base virtual. If not... DON'T! Very simple. Where things get a little more complex is with reusable code. Let's say you write a super duper special cl***: cl*** SuperDuperSpecial; You're not guaranteed that the "user" of your cl*** will not...(the aformentioned). Solution: A) Just declare the destructor virtual. B) Supply two forms: cl*** SuperDuperSpecialVirtualDestructor; |