How to invoke member function over by "const"?

Discussion in 'C++' started by recover, Aug 3, 2006.

  1. recover

    recover Guest

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

    class TConst
    {
    private:
    string con;
    string uncon;
    public:
    TConst():con("const"),uncon("Un const"){}
    string GetString()const;
    string& GetString();
    };
    //how can I invoke this member function?
    string TConst::GetString()const
    {
    return con;
    }
    string& TConst::GetString()
    {
    return uncon;
    }

    int main()
    {
    TConst tc;
    const string& csr=tc.GetString();
    const string cs=tc.GetString();
    string& sr=tc.GetString();
    string s=tc.GetString();

    cout<<"const string& csr="<<csr<<endl;
    cout<<"const string cs="<<cs<<endl;
    cout<<"string& sr="<<sr<<endl;
    cout<<"string s="<<s<<endl;
    }

    ===output=============
    const string& csr=Un const
    const string cs=Un const
    string& sr=Un const
    string s=Un const
    ===output end=====

    why all the call "GetString()" invoke the un const function.
    --
    = = = = = = = = = = = = = = = = = = = = = =

    ¡¡¡¡¡¡¡¡¡¡¡¡¡¡----------------------------
    Co.: beijing lingtu
    Ad.: beijing shangdi
    ZIP£º 100094
    Tel.: 010-82825800£­8006
    Mobile:
    Mail£º
    MSN:
    Com.£º http://www.lingtu.com/
    Online:http://www.51ditu.com/
    --------------------------
     
    recover, Aug 3, 2006
    #1
    1. Advertising

  2. recover wrote:
    > #include <string>
    > #include <iostream>
    > using namespace std;
    >
    > class TConst
    > {
    > private:
    > string con;
    > string uncon;
    > public:
    > TConst():con("const"),uncon("Un const"){}
    > string GetString()const;
    > string& GetString();
    > };
    > //how can I invoke this member function?


    You need a const object for that.

    > string TConst::GetString()const
    > {
    > return con;
    > }
    > string& TConst::GetString()
    > {
    > return uncon;
    > }
    >
    > int main()
    > {
    > TConst tc;


    The 'tc' is a NON-const object (in this scope, anyway).

    > const string& csr=tc.GetString();
    > const string cs=tc.GetString();
    > string& sr=tc.GetString();
    > string s=tc.GetString();
    >
    > cout<<"const string& csr="<<csr<<endl;
    > cout<<"const string cs="<<cs<<endl;
    > cout<<"string& sr="<<sr<<endl;
    > cout<<"string s="<<s<<endl;
    > }
    >
    > ===output=============
    > const string& csr=Un const
    > const string cs=Un const
    > string& sr=Un const
    > string s=Un const
    > ===output end=====
    >
    > why all the call "GetString()" invoke the un const function.


    Because all invocations are for the 'tc' object an it is non-const.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Aug 3, 2006
    #2
    1. Advertising

  3. recover

    Mark P Guest

    recover wrote:
    > #include <string>
    > #include <iostream>
    > using namespace std;
    >
    > class TConst
    > {
    > private:
    > string con;
    > string uncon;
    > public:
    > TConst():con("const"),uncon("Un const"){}
    > string GetString()const;
    > string& GetString();
    > };
    > //how can I invoke this member function?
    > string TConst::GetString()const
    > {
    > return con;
    > }
    > string& TConst::GetString()
    > {
    > return uncon;
    > }
    >
    > int main()
    > {
    > TConst tc;
    > const string& csr=tc.GetString();
    > const string cs=tc.GetString();
    > string& sr=tc.GetString();
    > string s=tc.GetString();
    >
    > cout<<"const string& csr="<<csr<<endl;
    > cout<<"const string cs="<<cs<<endl;
    > cout<<"string& sr="<<sr<<endl;
    > cout<<"string s="<<s<<endl;
    > }
    >
    > ===output=============
    > const string& csr=Un const
    > const string cs=Un const
    > string& sr=Un const
    > string s=Un const
    > ===output end=====
    >
    > why all the call "GetString()" invoke the un const function.


    Because the function that is called depends upon the object making the
    call (tc) and does not depend upon what you assign the result of the
    function call to. If you want to call the const member function then
    you need to invoke GetString on a const object.

    const TConst tc;
    tc.GetString();

    Or, you can cast a non-const TConst to a const TConst.
     
    Mark P, Aug 3, 2006
    #3
  4. recover posted:

    > why all the call "GetString()" invoke the un const function.



    class MyClass {
    public:

    void Func() {}

    void Func() const {}
    };

    int main()
    {
    MyClass obj;
    MyClass const cobj;

    obj.Func() /* Non-const version */
    cobj.Func() /* Const version */

    const_cast<MyClass const&>(obj).Func() /* Const version */


    /* Or if you have a phobia of "const_cast"
    (as many people here seem to have), then
    you can use a reference instead: */

    MyClass const &cr = obj;

    cr.Func(); /* Const Version */
    }


    I wonder would it be UB to call the non-const function on a const object
    (if the non-const function doesn't alter any member data)? Something like:

    const_cast<MyClass&>(cobj).Func();

    Anyone know if that's forbidden?

    --

    Frederick Gotham
     
    Frederick Gotham, Aug 3, 2006
    #4
  5. Frederick Gotham wrote:
    > ...
    > I wonder would it be UB to call the non-const function on a const object
    > (if the non-const function doesn't alter any member data)? Something like:
    >
    > const_cast<MyClass&>(cobj).Func();
    >
    > Anyone know if that's forbidden?
    > ...


    No, it is not UB. As long as (as you said) the member function doesn't alter any
    member data

    --
    Best regards,
    Andrey Tarasevich
     
    Andrey Tarasevich, Aug 3, 2006
    #5
  6. Andrey Tarasevich wrote:
    > Frederick Gotham wrote:
    >> ...
    >> I wonder would it be UB to call the non-const function on a const
    >> object (if the non-const function doesn't alter any member data)?
    >> Something like:
    >>
    >> const_cast<MyClass&>(cobj).Func();
    >>
    >> Anyone know if that's forbidden?
    >> ...

    >
    > No, it is not UB. As long as (as you said) the member function
    > doesn't alter any member data


    Why is the function that doesn't alter any data *not* declared 'const',
    that's what I'd be asking...

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Aug 3, 2006
    #6
  7. Victor Bazarov posted:

    > Why is the function that doesn't alter any data *not* declared 'const',
    > that's what I'd be asking...



    Instead of altering member objects, it could alter resources:

    class MyClass {

    int *const p;

    MyClass() : p(new int[64]) {}

    void SetElement(unsigned const index, int const val) /* Non-const */
    {
    p[index] = val;
    }
    };


    Depending on the design of the class, it might make perfect sense to make the
    above method non-const, even though it doesn't alter any member objects.

    --

    Frederick Gotham
     
    Frederick Gotham, Aug 3, 2006
    #7
  8. Frederick Gotham wrote:
    > Victor Bazarov posted:
    >
    >> Why is the function that doesn't alter any data *not* declared
    >> 'const', that's what I'd be asking...

    >
    >
    > Instead of altering member objects, it could alter resources:
    >
    > class MyClass {
    >
    > int *const p;
    >
    > MyClass() : p(new int[64]) {}
    >
    > void SetElement(unsigned const index, int const val) /* Non-const
    > */ {
    > p[index] = val;
    > }
    > };
    >
    >
    > Depending on the design of the class, it might make perfect sense to
    > make the above method non-const, even though it doesn't alter any
    > member objects.


    OK. I'll bite.

    If such function is non-const, why would somebody try to call it in the
    context where the object is const and thus requires a const_cast to call
    the non-const member function? If the design of the class is done right,
    there would be no circumstances under which a call to 'SetElement' needs
    to be done in a function where 'MyClass' object is const, do you agree?

    Generally speaking, it's not UB (what you asked about), but makes no
    sense in a well-designed program.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Aug 3, 2006
    #8
  9. recover

    mlimber Guest

    Frederick Gotham wrote:
    > Victor Bazarov posted:
    >
    > > Why is the function that doesn't alter any data *not* declared 'const',
    > > that's what I'd be asking...

    >
    >
    > Instead of altering member objects, it could alter resources:
    >
    > class MyClass {
    >
    > int *const p;
    >
    > MyClass() : p(new int[64]) {}
    >
    > void SetElement(unsigned const index, int const val) /* Non-const */
    > {
    > p[index] = val;
    > }
    > };
    >
    >
    > Depending on the design of the class, it might make perfect sense to make the
    > above method non-const, even though it doesn't alter any member objects.


    In the spirit of making as much const as possible, I prefer using
    wrappers and containers (e.g., std::vector) that enforce "deep
    constness" for their wrapped/contained values and applying mutable
    where that behavior is not desirable. Thus, your SetElement() function
    wouldn't be declared const, not just because it shouldn't be for
    semantic purposes, but because it *couldn't* be.

    Cheers! --M
     
    mlimber, Aug 3, 2006
    #9
  10. Victor Bazarov posted:

    > If such function is non-const, why would somebody try to call it in the
    > context where the object is const and thus requires a const_cast to call
    > the non-const member function? If the design of the class is done right,
    > there would be no circumstances under which a call to 'SetElement' needs
    > to be done in a function where 'MyClass' object is const, do you agree?
    >
    > Generally speaking, it's not UB (what you asked about), but makes no
    > sense in a well-designed program.



    Yes, I see what your getting at. But there are times when the programmer
    has to do some "funky stuff" to achieve something which can't be achieved
    via domestic means.

    Let's say that there's ONE instance in our program where we want to invoke
    this non-const method upon a const object; If we were to be perfectly
    politically correct about it, then we would re-engineer our design.

    But... then we might think, "Is it warranted to dump our brilliant design
    just because we circumvent it in one measly place?".

    My answer is "No". It's great for a design to be consistent, and durable,
    and all that... but in my opinion, there's nothing wrong with "digging
    under the fence" once or twice -- so long as it all comes together
    perfectly in the end.

    Think back to when you first encountered "const_cast". I think EVERY
    person's first reaction was, "Oh, this has GOT to be dirty; what could it
    possibly achieve legitimately?". Over time, we began to see that
    "const_cast" really isn't dirty at all -- it just provides us a way of
    "digging under the fence".

    So, depending on what our program does, and depending on what our class
    does, there may be legitimate places throughout the program where we invoke
    this non-const method upon a const object... ?

    --

    Frederick Gotham
     
    Frederick Gotham, Aug 3, 2006
    #10
  11. mlimber posted:

    >> Instead of altering member objects, it could alter resources:
    >>
    >> class MyClass {
    >>
    >> int *const p;
    >>
    >> MyClass() : p(new int[64]) {}
    >>
    >> void SetElement(unsigned const index, int const val) /* Non-const
    >> */ {
    >> p[index] = val;
    >> }
    >> };
    >>
    >>
    >> Depending on the design of the class, it might make perfect sense to
    >> make the above method non-const, even though it doesn't alter any
    >> member objects.


    > In the spirit of making as much const as possible, I prefer using
    > wrappers and containers (e.g., std::vector) that enforce "deep
    > constness" for their wrapped/contained values and applying mutable
    > where that behavior is not desirable. Thus, your SetElement() function
    > wouldn't be declared const, not just because it shouldn't be for
    > semantic purposes, but because it *couldn't* be.



    Not sure what you're getting at... ? In the above code, "SetElement" could
    certainly be defined as "const", as it doesn't alter any member objects.

    --

    Frederick Gotham
     
    Frederick Gotham, Aug 3, 2006
    #11
  12. recover

    Marcus Kwok Guest

    Frederick Gotham <> wrote:
    > mlimber posted:
    >> Frederick Gotham wrote:
    >>> Instead of altering member objects, it could alter resources:
    >>>
    >>> class MyClass {
    >>>
    >>> int *const p;
    >>>
    >>> MyClass() : p(new int[64]) {}
    >>>
    >>> void SetElement(unsigned const index, int const val) /* Non-const
    >>> */ {
    >>> p[index] = val;
    >>> }
    >>> };
    >>>
    >>>
    >>> Depending on the design of the class, it might make perfect sense to
    >>> make the above method non-const, even though it doesn't alter any
    >>> member objects.

    >
    >> In the spirit of making as much const as possible, I prefer using
    >> wrappers and containers (e.g., std::vector) that enforce "deep
    >> constness" for their wrapped/contained values and applying mutable
    >> where that behavior is not desirable. Thus, your SetElement() function
    >> wouldn't be declared const, not just because it shouldn't be for
    >> semantic purposes, but because it *couldn't* be.

    >
    > Not sure what you're getting at... ? In the above code, "SetElement" could
    > certainly be defined as "const", as it doesn't alter any member objects.


    What he said was:
    >> In the spirit of making as much const as possible, I prefer using
    >> wrappers and containers (e.g., std::vector) that enforce "deep
    >> constness" for their wrapped/contained values


    In other words, instead of using a raw pointer, he would prefer using
    e.g. a std::vector<int>.

    class MyClass {
    std::vector<int> p;

    MyClass() : p(64) {}

    void SetElement(unsigned const index, int const val)
    {
    p[index] = val;
    }
    };

    In this situation, you can not declare SetElement as const unless you
    make p mutable.

    --
    Marcus Kwok
    Replace 'invalid' with 'net' to reply
     
    Marcus Kwok, Aug 3, 2006
    #12
  13. Frederick Gotham wrote:
    > Victor Bazarov posted:
    >
    >> If such function is non-const, why would somebody try to call it in
    >> the context where the object is const and thus requires a const_cast
    >> to call the non-const member function? If the design of the class
    >> is done right, there would be no circumstances under which a call to
    >> 'SetElement' needs to be done in a function where 'MyClass' object
    >> is const, do you agree?
    >>
    >> Generally speaking, it's not UB (what you asked about), but makes no
    >> sense in a well-designed program.

    >
    >
    > Yes, I see what your getting at. But there are times when the
    > programmer has to do some "funky stuff" to achieve something which
    > can't be achieved via domestic means.


    In the world where design rules, there could not be such times.

    > Let's say that there's ONE instance in our program where we want to
    > invoke this non-const method upon a const object; If we were to be
    > perfectly politically correct about it, then we would re-engineer our
    > design.


    Yes.

    > But... then we might think, "Is it warranted to dump our brilliant
    > design just because we circumvent it in one measly place?".


    If our brilliant design allows for such situation to occur, it's not
    brilliant.

    > My answer is "No". It's great for a design to be consistent, and
    > durable, and all that... but in my opinion, there's nothing wrong
    > with "digging under the fence" once or twice -- so long as it all
    > comes together perfectly in the end.


    Here you go, you already used the sacramental "if". If you dig under
    the fence, how can you be sure that "all comes together perfectly"?
    I submit that you cannot.

    > Think back to when you first encountered "const_cast". I think EVERY
    > person's first reaction was, "Oh, this has GOT to be dirty; what
    > could it possibly achieve legitimately?". Over time, we began to see
    > that "const_cast" really isn't dirty at all -- it just provides us a
    > way of "digging under the fence".


    Hey, if it's in the language, it must be useful for something, right?

    > So, depending on what our program does, and depending on what our
    > class does, there may be legitimate places throughout the program
    > where we invoke this non-const method upon a const object... ?


    I've not seen _one_ such place. Honestly.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Aug 3, 2006
    #13
  14. recover

    Old Wolf Guest

    Frederick Gotham wrote:
    >
    > Yes, I see what your getting at. But there are times when the programmer
    > has to do some "funky stuff" to achieve something which can't be achieved
    > via domestic means.


    You're saying I can't always program from home? ;)
     
    Old Wolf, Aug 4, 2006
    #14
  15. recover

    Default User Guest

    Old Wolf wrote:

    > Frederick Gotham wrote:
    > >
    > > Yes, I see what your getting at. But there are times when the
    > > programmer has to do some "funky stuff" to achieve something which
    > > can't be achieved via domestic means.

    >
    > You're saying I can't always program from home? ;)


    You gotta put pants on sometimes.




    Brian
     
    Default User, Aug 4, 2006
    #15
  16. recover

    red floyd Guest

    Default User wrote:
    > Old Wolf wrote:
    >
    >> Frederick Gotham wrote:
    >>> Yes, I see what your getting at. But there are times when the
    >>> programmer has to do some "funky stuff" to achieve something which
    >>> can't be achieved via domestic means.

    >> You're saying I can't always program from home? ;)

    >
    > You gotta put pants on sometimes.
    >


    Sez you!!!!
     
    red floyd, Aug 4, 2006
    #16
  17. recover

    Tom Plunket Guest

    Victor Bazarov wrote:

    >Frederick Gotham wrote:
    >
    >> So, depending on what our program does, and depending on what our
    >> class does, there may be legitimate places throughout the program
    >> where we invoke this non-const method upon a const object... ?

    >
    >I've not seen _one_ such place. Honestly.


    While I agree with this in practice, there are times when I've used
    const_cast just to avoid having the same functionality in multiple
    places.

    E.g.:

    class MyClass
    {
    int& operator[](int i);
    const int& operator[](int i) const;
    };

    If the calculations to compute what to return are "complicated," it
    could be that one of these functions may want to const_cast in and out
    of constness for a call to the other version. There is no way that I
    know of to do this without const_cast unless you've got an
    internal/private method which is const but returns a non-const
    reference, but then you're breaking other rules anyway (and would it
    even compile?)...
     
    Tom Plunket, Aug 5, 2006
    #17
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    1
    Views:
    475
    Victor Bazarov
    Jul 20, 2005
  2. David Scarlett
    Replies:
    3
    Views:
    840
    mlimber
    Feb 7, 2006
  3. Javier
    Replies:
    2
    Views:
    571
    James Kanze
    Sep 4, 2007
  4. fungus
    Replies:
    13
    Views:
    892
    fungus
    Oct 31, 2008
  5. Markus Keppeler
    Replies:
    13
    Views:
    937
    Stuart Redmann
    Jul 29, 2011
Loading...

Share This Page