|
-
August 17th, 2012, 05:43 PM
#46
Re: Interview Questions
 Originally Posted by D_Drmmr
If every class should/must have a virtual destructor, you don't have the option of using the compiler implementation.
Your example didn't back up the claims you've made about the inefficiency of virtual destructors. I think you should acknowledge that.
You relied on a compiler dependent optimization. This backfired. The C++ standard doesn't state compiler generated destructors must be faster than user supplied empty ones. So generally it's a bad idea to bet on this for the performance of a program. And it's even worse to recommend others to do it.
It's called premature optimization. In my view many C++ programmers spend too much time fiddling with implementation detail they don't know will have any impact on the overall application performance. If you have this inclination it's better to use C. Far less abstraction and much more sweating the small stuff.
Last edited by nuzzle; August 18th, 2012 at 05:27 PM.
-
August 19th, 2012, 01:33 PM
#47
Re: Interview Questions
 Originally Posted by STLDude
Are you advocating to actually make virtual destructor for any class even if it does not have any other virtual methods?
And again...
The need for a virtual destructor has NO RELEVANCE AT ALL to the class having other virtual functions.
see previous posts...
And no, I'm not advocating adding virtual to all destructors.
But on all classes that may get useed as a base class by someone other than you. It's probably a good idea.
Rereading my own answer on this... I guess what I really wanted to say...
It is a better to get into a habbit of making all your destructors virtual by default and asking yourself if it really needs to be, than doing the opposite. Making them non-virtual by default and asking yourself if it maybe needs to be virtual.
Doing the former, will almost never result in failing code, only in code that's "a bit" slower than it needs to be.
Doing the latter, could result in a program that leaks, crashes, or does all sorts of nasty things.
Last edited by OReubens; August 19th, 2012 at 02:00 PM.
-
August 19th, 2012, 01:54 PM
#48
Re: Interview Questions
 Originally Posted by D_Drmmr
First of all, I don't understand what virtual machines or intermediate languages have to do with C++.
I was merely pointing out a trend. THere is a growing trend in using "higher level" languages that add extra layers between what you wrote and the actual hardware. All those layers take time as well. If people accept the added performance loss of those extra layers. Then the extra performance lost of virtual destructors over regular ones is negligeable.
 Originally Posted by D_Drmmr
Second, it is a big deal when your class is, say, an iterator that only wraps a single pointer. If all of the classes in the STL would have virtual destructors, I would certainly not be happy. There is no reason to use these classes in a runtime polymorphic way, so they don't need a virtual destructor. Adding one can cause major performance penalties. Here's a little test I did with VS2005. The cost of this premature pessimization in this case is a factor 3.8 performance loss. That's a big deal!
And you can "proove" just about anything this way. 
I never claimed that making a destructor virtual has no performance implications.
But in this particular instance. We're talking about a performance lost of 5 sec over 500million iterations.
Yes, it's 5sec difference. but with an example that's tailored into forcing a bad result.
5sec lost over 500million iterations is "negligeable" most of the time.
I can proove that all STL algoritms are "bad" if I "proove" that each of them against their worst case scenario does significantly less than algorithms tailored to those specific worst cases.
Note that I never claimed to just add virtual to everything. classes you are 100% sure that will never be derived from don't need it.
But if you are designing libs, you don't always know how users of your lib will use the classes you design. So adding virtual to "all" classes is probably a good idea. iterators are probably one of the few cases where you can be sure people will never derive of them. If you have all the code under your own control. THen stuff is always easier
-
August 19th, 2012, 02:16 PM
#49
Re: Interview Questions
 Originally Posted by D_Drmmr
As superbonzo, I also read OReubens' suggestion as using virtual destructors for every class (or struct), even those that have no virtual functions and, therefore, are not designed to be used in an OO way. That just doesn't make sense to me. IMO, you gain nothing and potentially loose a lot.
Performance is a secondary issue. Your users are not going to love you if you make the fastest possible code that crashes. Or makes their machine go wonky.
Code that works is the more important issue.
Adding virtual anywhere "just in case" is thus the better strategy. That doesn't mean optimisation has no relevance at all. If you can 100% guarantee a class will never be deleted polymorphically then you can remove the virtual and gain some performance.
If you can 100% guarantee the class will not ever by anyone using your code now or in the future be deleted polymorphically, then don't add the virtual. In all other cases "it is probably a good idea to do it anyway".
Every base class that has virtual functions gets a virtual destructor - no problem there.
And you too seem to imply a relation to the class having other virtual functions. Again, THIS IS NOT what decides the need for a virtual destructor.
The ONLY thing that makes a virtual destructor necessary is if you new a derived class and delete it through it's base pointer.
If you're not doing this, then you don't need a virtual destructor, regardless of if the class (or base class) has
or doesn't have virtual members.
Last edited by OReubens; August 19th, 2012 at 02:20 PM.
-
August 19th, 2012, 03:47 PM
#50
Re: Interview Questions
 Originally Posted by OReubens
iterators are probably one of the few cases where you can be sure people will never derive of them.
Sorry, but you cannot be sure of that.
 Originally Posted by OReubens
If you can 100% guarantee the class will not ever by anyone using your code now or in the future be deleted polymorphically, then don't add the virtual. In all other cases "it is probably a good idea to do it anyway".
Unless the destructor is non-public, or the class is defined in an unnamed namespace in one of your source files, you cannot "100% guarantee (that an object of) the class will not ever by anyone using your code now or in the future be deleted polymorphically".
I think that your approach is pragmatic. That's good. But just as you have such confidence about C++ programmers when it comes to deriving from iterators, I have confidence that C++ programmers understand that they should not be publicly deriving from a class that is not designed to be a polymorphic base class such that objects of derived classes will be destroyed by deleting a pointer to the base class. If they betray my confidence, then it is their foolishness.
Consequently, I would rather signal this by not declaring the destructor virtual if I really do intend my class to be a concrete class that does not serve as a polymorphic base class. It may be inconvenient to a user of the class if he/she wants to derive from it, but that is likely to be a sign that public inheritence is a wrong design to begin with.
 Originally Posted by OReubens
Rereading my own answer on this... I guess what I really wanted to say...
It is a better to get into a habbit of making all your destructors virtual by default and asking yourself if it really needs to be, than doing the opposite. Making them non-virtual by default and asking yourself if it maybe needs to be virtual.
I don't think we should have a habit of making destructors virtual or non-virtual by default. We should have a habit of making our destructors virtual or non-virtual by intention.
 Originally Posted by OReubens
And you too seem to imply a relation to the class having other virtual functions. Again, THIS IS NOT what decides the need for a virtual destructor.
The ONLY thing that makes a virtual destructor necessary is if you new a derived class and delete it through it's base pointer.
If you're not doing this, then you don't need a virtual destructor, regardless of if the class (or base class) has
or doesn't have virtual members.
When you talk about "need" here, I definitely agree. Note that in post #6, the word used is "should". I'm not going to quibble on this though, since you later conceded:
 Originally Posted by OReubens
I will sort of agree that a class with virtual members is a likely candidate for needing a virtual destructor as well (without conclusions about the opposite). But that relation is much much less of a formal rule than than say the relation between a class that has a copy constructor also needing an assign operator (or vice versa).
Which is also something that I agree with. (However, I note that your related example is unclear: a class that has a copy constructor defined does not always need to have a copy assignment operator defined, since it could be the case that the copy assignment operator is declared private but not defined.)
-
August 20th, 2012, 10:03 AM
#51
Re: Interview Questions
 Originally Posted by OReubens
1) Performance is a secondary issue.
2) Code that works is the more important issue.
3) Adding virtual anywhere "just in case" is thus the better strategy.
Your logic is wrong. I agree with 1 and 2, but 3 is in direct conflict with 2.
By making all your methods virtual, you are allowing users to "hijack" them by over-riding them. Once you have "published" your class, you will not be able to maintain it anymore, as you'll have absolutely no idea how a third party user may have re-interpreted your function. At this point, changing anything in your code will potentially break your client's code, and I can guarantee you they'll hate that more than anything else.
Ignoring performance, the easiest way to write code that works is to write code that is closed and simple. Polymorphism is an open concept, and is not simple.
Is your question related to IO?
Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.
-
August 20th, 2012, 11:09 AM
#52
Re: Interview Questions
 Originally Posted by OReubens
But in this particular instance. We're talking about a performance lost of 5 sec over 500million iterations.
Yes, it's 5sec difference. but with an example that's tailored into forcing a bad result.
5sec lost over 500million iterations is "negligeable" most of the time.
Don't take this the wrong way, but hat really makes me wonder what kind of software you develop.
 Originally Posted by OReubens
Performance is a secondary issue. Your users are not going to love you if you make the fastest possible code that crashes. Or makes their machine go wonky.
Code that works is the more important issue.
Adding virtual anywhere "just in case" is thus the better strategy.
If I take a working application or library and start making all kinds of non-virtual member functions (or even just destructors) virtual that doesn't make make the code work any better. If a library user derives from a class with a non-virtual destructor and deletes a pointer to the base class, then the user's code is wrong.
I agree with laserlight that if you design a class library, you should make the intent clear. If your intention is that a class is not derived from then don't make the destructor virtual. If your intention is for a class to be used polymorphically, then make the destructor virtual, just in case a user wants to be able to safely delete a pointer to the base class.
 Originally Posted by OReubens
And you too seem to imply a relation to the class having other virtual functions. Again, THIS IS NOT what decides the need for a virtual destructor.
I don't think it makes much sense to talk about the need for a virtual destructor, because this depends on the code path that is taken at runtime. If a certain code path is never taken (perhaps just because the required input is never actually used) then strictly speaking there is no need for that code path to prevent runtime errors.
We are talking here about guidelines. I find the guideline to add a virtual destructor to any base class that has virtual methods a good one, because (1) if the class is designed to be used polymorphically (indicated by the virtual functions) that it is not unlikely that at some point a pointer to the base class should be deleted and (2) if the class has no virtual functions then I don't see a reason to store a pointer to this class, which points to a newed instance of a derived class. The only reason I can think of would be to store different types of objects in a single container, which can be achieved better using something like boost::variant or boost::any. If you have any more convincing use cases in mind, I'd be interested to hear them.
Cheers, D Drmmr
Please put [code][/code] tags around your code to preserve indentation and make it more readable.
As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|