CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 4 of 4 FirstFirst 1234
Results 46 to 52 of 52
  1. #46
    Join Date
    May 2009
    Posts
    2,413

    Re: Interview Questions

    Quote Originally Posted by D_Drmmr View Post
    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.

  2. #47
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: Interview Questions

    Quote Originally Posted by STLDude View Post
    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.

  3. #48
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: Interview Questions

    Quote Originally Posted by D_Drmmr View Post
    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.



    Quote Originally Posted by D_Drmmr View Post
    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

  4. #49
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: Interview Questions

    Quote Originally Posted by D_Drmmr View Post
    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.

  5. #50
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: Interview Questions

    Quote 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.

    Quote 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.

    Quote 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.

    Quote 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:
    Quote 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.)
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  6. #51
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,513

    Re: Interview Questions

    Quote Originally Posted by OReubens View Post
    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.

  7. #52
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,042

    Re: Interview Questions

    Quote Originally Posted by OReubens View Post
    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.
    Quote Originally Posted by OReubens View Post
    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.
    Quote Originally Posted by OReubens View Post
    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

Page 4 of 4 FirstFirst 1234

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured