Thread: Class method overloading

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Registered User
    Join Date
    Apr 2007
    Posts
    141

    Class method overloading

    This has been one of my deepest forays into C++ programming, having been scared off in the past by the arcana of memory management . I 'cured' my memory management problems by incorporating garbage collection thanks to Hans Boehm. (OK I don't like writing destructors or remembering when to call them.)

    I now however have run into an interesting problem with function overloading in an inherited class.
    I have a situation that looks something like this:

    Code:
    class Foo {
    public:
    void setdims()
    {
    .....
    }
    
    void func1 ()
    {
    setdims() ;
    }
    
    } ;  /* end class Foo */
    
    class Bar: public Foo {
    public:
    void setdims()
    {
    .....  /* different implementation */
    }
    
    } ; /* end class Bar */
    I did not label setdims() as virtual since the behavior I want is for setdims to be overloaded for a class of type Bar and the Foo's setdims() to be hidden. However what happens when I call the inherited function func1() for a class of type Bar? (e.g. Bar x ; x.func1() ; ) Apparently with MS's compiler it calls Foo's setdims() and not Bar's setdims(). This is not the behavior I want. Basically I'd like to reuse Foo's code, since the only major functional change for many methods is what get's allocated in the function setdims(). Thus I'd like to call the parent's class func1() but have it call the overloaded setdims() not the parent's setdims().

    How do I fix this? Do I need the virtual descriptor here? Is this what is supposed to happen?
    Thanks in advance for your help.

  2. #2
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    (OK I don't like writing destructors or remembering when to call them.)
    Err . . . you shouldn't have to call destructors. They should automatically be called when a class goes out of scope or is deleted. Perhaps you meant that you don't like remembering when to delete classes.

    I did not label setdims() as virtual since the behavior I want is for setdims to be overloaded for a class of type Bar and the Foo's setdims() to be hidden.
    I think that's what virtual functions are supposed to do, isn't it?
    From an OO perspective, it is the single most important feature of C++: [6.9], [6.10].

    A virtual function allows derived classes to replace the implementation provided by the base class. The compiler makes sure the replacement is always called whenever the object in question is actually of the derived class, even if the object is accessed by a base pointer rather than a derived pointer. This allows algorithms in the base class to be replaced in the derived class, even if users don't know about the derived class.

    The derived class can either fully replace ("override") the base class member function, or the derived class can partially replace ("augment") the base class member function. The latter is accomplished by having the derived class member function call the base class member function, if desired.
    http://www.parashift.com/c++-faq-lit...functions.html

    So yes, I think you should try making Foo's setdims() virtual. (virtual functions that are overloaded automatically have "virtual" in front of them, or at least they act that way; but putting "virtual" in front of Bar's setdims() can't hurt.)
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  3. #3
    Registered User
    Join Date
    Apr 2007
    Posts
    141
    Quote Originally Posted by dwks View Post
    Err . . . you shouldn't have to call destructors. They should automatically be called when a class goes out of scope or is deleted. Perhaps you meant that you don't like remembering when to delete classes.
    Yes that's what I meant thanks, and by the way how nice it is to not have to worry about that stuff. I suppose I could have also played around with some of those smart pointer types as well to help with this, but garbage collection seems to work pretty well if you have memory to burn.

    I think that's what virtual functions are supposed to do, isn't it?

    http://www.parashift.com/c++-faq-lit...functions.html

    So yes, I think you should try making Foo's setdims() virtual. (virtual functions that are overloaded automatically have "virtual" in front of them, or at least they act that way; but putting "virtual" in front of Bar's setdims() can't hurt.)
    Yes I just tried it and you are correct, it seems to fix the problem and it even makes sense now. Moreover I don't think the virtual table overhead will be an issue for my problem either. Thanks for the help.

  4. #4
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by SevenThunders View Post
    This has been one of my deepest forays into C++ programming, having been scared off in the past by the arcana of memory management . I 'cured' my memory management problems by incorporating garbage collection thanks to Hans Boehm. (OK I don't like writing destructors or remembering when to call them.)
    GC is a pretty hackish solution to resource management in C++, since we have containers, smart pointers, and RAII. I would hate to think that my objects might never be deleted at all, at the whim of the GC, or deleted in an order I have no control over.

    As far as overriding methods, whether you use "virtual" depends on whether you want to make calls to the objects through a pointer or reference to one of its base classes. Since you use GC, I assume you've got pointers all over the dang place, and so you probably want to be using "virtual." Polymorphism can't work without it.

  5. #5
    Registered User
    Join Date
    Apr 2007
    Posts
    141
    Quote Originally Posted by brewbuck View Post
    GC is a pretty hackish solution to resource management in C++, since we have containers, smart pointers, and RAII. I would hate to think that my objects might never be deleted at all, at the whim of the GC, or deleted in an order I have no control over.

    As far as overriding methods, whether you use "virtual" depends on whether you want to make calls to the objects through a pointer or reference to one of its base classes. Since you use GC, I assume you've got pointers all over the dang place, and so you probably want to be using "virtual." Polymorphism can't work without it.
    I don't know why it's that hack'ish. Java, D, Haskell, O'Caml and many other useful languages use garbage collection. The only real performance hit is that it's not as memory efficient but then again memory is cheap. IMHO C++ tends to generate a lot of memory leaks, especially for beginners like me.

    I think it makes C++ a lot more pleasant to program, but then I haven't messed around with some of the smart pointer stuff yet.

  6. #6
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by SevenThunders View Post
    I don't know why it's that hack'ish. Java, D, Haskell, O'Caml and many other useful languages use garbage collection. The only real performance hit is that it's not as memory efficient but then again memory is cheap. IMHO C++ tends to generate a lot of memory leaks, especially for beginners like me.

    I think it makes C++ a lot more pleasant to program, but then I haven't messed around with some of the smart pointer stuff yet.
    One of the things I don't like about languages like Java is that they have a new keyword, but no delete. Yes, it has garbage collection, but what if I don't want to wait for something that might never happen? I also want destructors and stack based objects so I can have RAII objects...

  7. #7
    Registered User
    Join Date
    Apr 2007
    Posts
    141
    Quote Originally Posted by cpjust View Post
    One of the things I don't like about languages like Java is that they have a new keyword, but no delete. Yes, it has garbage collection, but what if I don't want to wait for something that might never happen? I also want destructors and stack based objects so I can have RAII objects...
    I confess I have never even heard of RAII until now. It sounds interesting, I see how it could be useful. You are correct that in most languages where the garbage control is built in, you do not have fine control over the collector. With the Hans Boehm collector you do have control in that you can explicitly free or suspend the collector if you need a computation to run in a finite period of time etc.

    Here is some propaganda with regards to D's garbage collector.
    http://www.digitalmars.com/d/2.0/garbage.html
    I guess it's possible to control the behavior of D's collector as well to some extent.

  8. #8
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by SevenThunders View Post
    I don't know why it's that hack'ish. Java, D, Haskell, O'Caml and many other useful languages use garbage collection.
    I believe I qualified my statement with the words "in C++..." There are better ways to do it in C++.

    Java forces you to "new" everything, there is no such thing as an automatic variable, and it gives you no "delete" and so the only choice is GC.

    Haskell and O'Caml aren't even imperative languages so they inherently can't support a concept such as RAII -- well, at least without using those "monad" things.

    And I have no idea about D.

    GC makes sense in a lot of languages. I think C++ is not one of them.

  9. #9
    Registered User
    Join Date
    Apr 2007
    Posts
    141
    Quote Originally Posted by brewbuck View Post
    I believe I qualified my statement with the words "in C++..." There are better ways to do it in C++.

    Java forces you to "new" everything, there is no such thing as an automatic variable, and it gives you no "delete" and so the only choice is GC.

    Haskell and O'Caml aren't even imperative languages so they inherently can't support a concept such as RAII -- well, at least without using those "monad" things.

    And I have no idea about D.

    GC makes sense in a lot of languages. I think C++ is not one of them.
    I know we are drifting waaaay off topic, but it is an interesting point to some extent. I think most C++ programmers would agree with you. However I still think GC has some good applications in C++. It eases the burden of writing destructors, worrying about dangling references etc. and is actually has some performance benefits when a lot of small objects are being created and destroyed. Even Microsoft has a compacting GC with it's "Managed C++", though I understand it requires a language extension.

    For memory critical applications and if real time is important, then I will concede the point.

  10. #10
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    I just can't see what's so scary about writing destructors? Most of the time, I don't even need one since I don't create many object-level pointers... but if I allocate something in the constructor, I deallocate it in the destructor.

  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by SevenThunders View Post
    I know we are drifting waaaay off topic, but it is an interesting point to some extent. I think most C++ programmers would agree with you. However I still think GC has some good applications in C++. It eases the burden of writing destructors, worrying about dangling references etc.
    You are basing this on that you have to do everything manually. You don't. You can use smart pointers and never worry about not freeing memory. Classes are very, very useful. RAII especially, since you can pretty much encapsulate anything and let the class worry about it.
    Got heap allocated memory? No problem. Got pesky "handles"? No problem.
    And I also think you miss the point of writing destructors and are afraid of them. You shouldn't be. A destructor should merely handle things that needs to be done when a class is destroyed. It doesn't just stoop to freeing resources.
    Say you encapsulate a file with a class. So long as the class exists, it makes sense the file exists. But when the object is destroyed, the file is closed. This is handled in the destructor. But with garbage collecting, the file might not be closed when the object is no longer used.
    I actually saw beware of GC, because it really destroys C++'s RAII concept.
    It's far better to use smart pointers.

    Quote Originally Posted by SevenThunders View Post
    Even Microsoft has a compacting GC with it's "Managed C++", though I understand it requires a language extension.
    This is also not true. "Managed C++" or the newest, C++/CLI is essentially a C++ version that is designed to work with Microsoft's .NET Framework. And it just happens that their framework has a garbage collector. That's all.

    Quote Originally Posted by SevenThunders View Post
    For memory critical applications and if real time is important, then I will concede the point.
    Again, I don't really think I would agree. If such is the case, then manual deleting at right spots would be far more efficient than a GC.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  12. #12
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    The object isn't deleted until all references to it have gone out of scope.
    And could we get the report of all objects that could not be freed acording to GC at some time?

    All memory that is leaked in the regular working mode could be reported by tools like BoundsChecker. Is there a tool like this for GC?
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  13. #13
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Based on his online FAQ answers, I daresay Stroustrup thinks that garbage collection does have its uses in C++, at least as a last resort. Consider the last paragraph of his answer to How do I deal with memory leaks?:
    Quote Originally Posted by Bjarne Stroustrup
    If systematic application of these techniques is not possible in your environment (you have to use code from elsewhere, part of your program was written by Neanderthals, etc.), be sure to use a memory leak detector as part of your standard development procedure, or plug in a garbage collector.
    He does not condemn garbage collection, but states in his answer to Why doesn't C++ have garbage collection?:
    Quote Originally Posted by Bjarne Stroustrup
    If you want automatic garbage collection, there are good commercial and public-domain garbage collectors for C++. For applications where garbage collection is suitable, C++ is an excellent garbage collected language with a performance that compares favorably with other garbage collected languages.
    That FAQ links to Hans-J. Boehm's GC implementation that SevenThunders mentioned.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  14. #14
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    part of your program was written by Neanderthals
    I run into this problem far too often.

  15. #15
    Banned
    Join Date
    Nov 2007
    Posts
    678
    if a slow language like java can afford overhead of GC, then why a super fast language like C++ has problems with it being inefficient???
    Last edited by manav; 03-25-2008 at 02:49 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. calling a class method within different class method
    By alyeska in forum C++ Programming
    Replies: 5
    Last Post: 03-08-2009, 10:56 AM
  2. Windows Service class constructor and OnStart method
    By George2 in forum C# Programming
    Replies: 0
    Last Post: 04-14-2008, 07:18 AM
  3. Overloading an "External" Class?
    By Zeusbwr in forum C# Programming
    Replies: 2
    Last Post: 10-30-2005, 04:34 PM
  4. problem with sending files to a class method..
    By utoots in forum C++ Programming
    Replies: 5
    Last Post: 04-02-2003, 01:38 AM
  5. Warnings, warnings, warnings?
    By spentdome in forum C Programming
    Replies: 25
    Last Post: 05-27-2002, 06:49 PM