CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 16
  1. #1
    Join Date
    Apr 2004
    Location
    Los Angeles
    Posts
    50

    How do you call "func()" vs "func() const"?

    Code:
    class Foo
    {
      Foo() { }
      int func(int a)
      { return 0; }
    
      int func(int a) const
      { return 1; }
    }
    
    int main()
    {
      Foo foo;
    
      foo.func();
    }
    In the example above, how do I know which func I'm calling? More to the point, how do I call the one with the const?

  2. #2
    Join Date
    May 2005
    Posts
    99

    Re: How do you call "func()" vs "func() const"?

    #include <iostream>
    #include <string>
    using namespace std;

    class Foo
    {
    public:
    Foo() { }
    int func(int a)
    { cout << a++ << endl; return 0; }

    int func(int a) const
    { cout << --a << endl;return 1; }
    };

    int main()
    {
    int i = 10;
    Foo foo;
    foo.func(i);
    Foo const foo1;
    foo1.func(i);
    }

  3. #3
    Join Date
    Nov 2002
    Location
    Foggy California
    Posts
    1,245

    Re: How do you call "func()" vs "func() const"?

    Quote Originally Posted by ecspansion
    In the example above, how do I know which func I'm calling? More to the point, how do I call the one with the const?
    A const object will call const functions. A non-const object will call non-const functions.

    But more about your real question -- how do you call the one with const. In general, you should not worry about this. If a function has both a const and a non-const overload, they should perform the same action. Usually this means that the const overload will return a const-reference to some internal variable while the non-const overload will return a non-const reference to the same variable. It would be a very poor design for the two overloads to perform different types of actions.

    I hope this makes sense.

    - Kevin
    Kevin Hall

  4. #4
    Join Date
    Oct 2000
    Location
    London, England
    Posts
    4,773

    Re: How do you call "func()" vs "func() const"?

    Probably why they didn't implement std::map with a const-overload for operator[]. Not because it couldn't find anything to return when the item doesn't exist, it could return a const reference to a default of the the second value (i.e. T()) or even a copy of one, but because operator[] when non-const has the side-effect of inserting when the element is not found.

    Thus

    Code:
    #include <map>
    #include <string>
    int main()
    {
       std::map< int, std::string > m;
       m[1] = "hello";
       m[4] = "world";
       std::cout << m[1] << ' ' << m[4] << ' ' << m[5] << '\n';
       if ( m.find( 5 ) != m.end() )
       {
             std::cout << "m[5] exists\n";
       }
      else
       {
           std::cout << "m[5] does not exist\n";
       }
    }
    And you will probably find that m[5] exists (and will be an empty string).

    Note that the non-const overload is always called in preference if possible.

  5. #5
    Join Date
    Jul 2005
    Posts
    103

    Re: How do you call "func()" vs "func() const"?

    If you want to specifically call the const version for a non-const object use
    Code:
    static_cast<const Foo&>(foo).func(1);
    const_cast works as well of course but the"style" guideline of most (authors) is to use static_cast to add const-ness.

  6. #6
    Join Date
    Oct 2000
    Location
    London, England
    Posts
    4,773

    Re: How do you call "func()" vs "func() const"?

    Generally bad design if you have to do that. If I did decide to I'd probably get a const reference to point to the non-const instance and call it from the const-reference.

    Thus:
    Code:
    Foo foo;
    const Foo& foocref( foo );
    foocref.method(); // will call const overload

  7. #7
    Join Date
    Feb 2005
    Location
    Normandy in France
    Posts
    4,590

    Thumbs up Re: How do you call "func()" vs "func() const"?

    Quote Originally Posted by freddyflintstone
    const_cast works as well of course but the"style" guideline of most (authors) is to use static_cast to add const-ness.
    Of course, it is better to use static_cast, because static_cast can only add const specifiers. It is not dangerous.
    const_cast can remove const specifier, and should be avoided if possible (but it cannot be always avoided, for example when linking with libraries which don't use const specifiers).

  8. #8
    Join Date
    Jun 2002
    Posts
    1,417

    Re: How do you call "func()" vs "func() const"?

    If both the const and non-const functions do the same thing as Keven said, what difference does it make which one get called? The calling function shouldn't care because the result is the same either way (except of course for the const modifier).

  9. #9
    Join Date
    Oct 2000
    Location
    London, England
    Posts
    4,773

    Re: How do you call "func()" vs "func() const"?

    Quote Originally Posted by stober
    If both the const and non-const functions do the same thing as Keven said, what difference does it make which one get called? The calling function shouldn't care because the result is the same either way (except of course for the const modifier).
    Well of course you and I wouldn't design a class where you'd want to explicitly call a const-overload, but maybe we're using someone else's badly designed class (and can't change it).

    Now we're discussing which is the best way to work around it (i.e. create a const reference or cast).

  10. #10
    Join Date
    Jul 2005
    Posts
    103

    Re: How do you call "func()" vs "func() const"?

    Quote Originally Posted by NMTop40
    Generally bad design if you have to do that. If I did decide to I'd probably get a const reference to point to the non-const instance and call it from the const-reference.

    Thus:
    Code:
    Foo foo;
    const Foo& foocref( foo );
    foocref.method(); // will call const overload
    Bad design sure but the above 2 methods just answers the question. Here's another way to force a call to the const onverload. Its even more reprehensible.
    Code:
    int (Foo::*f)() const = &Foo::func;
    (foo.*f)(0);

  11. #11
    Join Date
    Nov 2002
    Location
    Foggy California
    Posts
    1,245

    Re: How do you call "func()" vs "func() const"?

    You guys have spent a lot of time explaining the work-arounds for a poorly written library. While I understand the desire to work-around something poorly designed, and calling a const-method from a non-const variable is "safe", the next question I worry, will be the other way around: "How do I call a non-const method if I have a const-variable?" This is not safe and leads to undefined behavior. If today you have a need today to go one way, you'll have the need tomorrow to go the other, and then you're in the realm of undefined behavior. Very, very scary!!!

    I have seen libraries where const was never used, and that required const_cast's to remove const-ness. This made me very nervous, but I could understand that perhaps this was someone (or some group) who just hadn't learned the value of const, and hope that at least that the code underneath was consistent and would not violate assumed const-ness.

    But to have a library that has both const and non-const methods and where the methods do different things, that scares me a LOT because then it indicates that the library designers didn't have a consistent idea about what the library was supposed to do. It also may indicate that the library designers can't communicate with eachother. It will lead to maintenance nightmares in the future for both me as a user and the library designers themselves. Personally, if I had any say in the matter, I'd stay clear of any library where the const and non-const methods differed in what they were supposed to do.

    I REALLY hope that the OP was more of an accademic question rather than something he is being forced to deal with.
    Kevin Hall

  12. #12
    Join Date
    May 2004
    Location
    Michigan, United States
    Posts
    457

    Re: How do you call "func()" vs "func() const"?

    But to have a library that has both const and non-const methods and where the methods do different things, that scares me a LOT because then it indicates that the library designers didn't have a consistent idea about what the library was supposed to do.
    I don't see anything wrong with having two function declarations differing only in their constness. And obviously the developers of the C++ language didn't either, or else they would have chosen to decorate the names the same.

    To me, you're simply saying that one function will modify member data, whereas the other won't. Casting aside, a const object will call the const member function while a non-const object will call the non-const member function. Sounds perfect to me.

    As for the poster's question -- you know by the constness of your object. And as KevinHall said, if you have to resort to casts to call the other function, then you need to redesign.
    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs and the Universe trying to produce bigger and better idiots. So far, the Universe is winning.

  13. #13
    Join Date
    Nov 2002
    Location
    Foggy California
    Posts
    1,245

    Re: How do you call "func()" vs "func() const"?

    Bond, you misinterpreted my post. I agree with what you said (please see my first post in this thread).

    If someone needs to cast an object so he can call a method of different const-ness, then this implies that the const and non-const methods do something functionally different; and this is what scares me. For example:

    Code:
    class Foo
    {
    public:
        double MathOperation(double x)
        {
            return x*x;
        }
    
        double MathOperation(double x) const
        {
            return sqrt(x);
        }
    };
    This is obviously poor design, and something I would want to avoid! I hope this clears up any confusion about what I said.
    Kevin Hall

  14. #14
    Join Date
    Apr 2004
    Location
    Los Angeles
    Posts
    50

    Re: How do you call "func()" vs "func() const"?

    Thanks for the responses everyone.

    I don't believe the library to be designed poorly, the designers just wanted different behavior for different objects - in this case, both funcs return the same data. I'm using this func on data that must be modified before using it, but shouldn't be changed by the function so some sort of a cast or const pointer/reference is required.

    hmmm... I suppose it would have been more clear if the functions had different names & therefore could be called explicitly w/o casts.

    Thanks again.
    Last edited by ecspansion; July 29th, 2005 at 01:47 PM.

  15. #15
    Join Date
    Feb 2005
    Location
    Normandy in France
    Posts
    4,590

    Re: How do you call "func()" vs "func() const"?

    Quote Originally Posted by ecspansion
    Thanks for the responses everyone.

    I don't believe the library to be designed poorly, the designers just wanted different behavior for different objects - in this case, both funcs return the same data. I'm using this func on data that must be modified before using it, but shouldn't be changed by the function so some sort of a cast or const pointer/reference is required.

    hmmm... I suppose it would have been more clear if the functions had different names & therefore could be called explicitly w/o casts.

    Thanks again.
    If there is a const member with the same name that a non-const member, since the two functions must be functionally identical, the non-const member function must not modify the object (but may cache some informations, or, for a monothread application, may modify the object data during the processing, and restore it before returning). For the programmer they behaves exactly the same, even if the non-const function may do some optimizations (very rarely, i mainly think to put a temporary null terminator in a string when parsing it).
    In fact, writing two functions having the same name, one const, the other non-const, is generally used to return references or pointers which have the same attributes, and the assembly code is basically exactly the same.

    So, don't matter which function is called, the contract of these two functions is exactly the same. If that is not the case, it signs a design flaw.
    To correct this design flaw, you should change the name of these member functions (at least one, maybe the two functions, since their names don't say what they do).

Page 1 of 2 12 LastLast

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