Results 1 to 23 of 23

Thread: return type: const reference?!

  1. #1
    jim mcnamara
    Guest
    this is a pointer to a window object. the pointer never changes value - points to the same form/window all the time. In this case it looks like you are are returning a refernce to a particular window.

  2. #2
    Junior Member
    Join Date
    Dec 2001
    Location
    Melbourne - Australia
    Posts
    27
    what do you mean by "window object"? this is a console program, not a window program. what i want to know is why declare the operator++ function with a const return type? i just dont see what the point is. i'll quote the tutorial im using:

    "It is a const reference because the value should not be changed by the function using this Counter."

    const Counter& operator++ ()
    {
    ++itsVal;
    return *this;
    }

    why shouldn't the value be changed? it is supposed to change, the idea is to increment it!

  3. #3
    Hyperactive Member
    Join Date
    Sep 2001
    Posts
    396
    It is not saying the value cannot be changed.

    It is saying the *this pointer should not be changed.

    It is the *this pointer which is returned as reference.

    One thing I am not sure is for operator overloading, why must it be always returning *this as ref. Anyone?
    I'm a VB6 beginner.

  4. #4
    transcendental analytic kedaman's Avatar
    Join Date
    Mar 2000
    Location
    0x002F2EA8
    Posts
    7,221
    Originally posted by bruce_smith
    what do you mean by "window object"? this is a console program, not a window program. what i want to know is why declare the operator++ function with a const return type? i just dont see what the point is. i'll quote the tutorial im using:

    "It is a const reference because the value should not be changed by the function using this Counter."

    const Counter& operator++ ()
    {
    ++itsVal;
    return *this;
    }

    why shouldn't the value be changed? it is supposed to change, the idea is to increment it!
    I don't see the point either. Remove const modifier, it's your program (isn't it?).
    Const objects are only returned when you want them to be protected from changes from outside.
    Use
    writing software in C++ is like driving rivets into steel beam with a toothpick.
    writing haskell makes your life easier:
    reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
    To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.

  5. #5
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    Originally posted by kedaman
    I don't see the point either. Remove const modifier, it's your program (isn't it?).
    Const objects are only returned when you want them to be protected from changes from outside.
    And also, it means that it can optimise it out.

    There are two ways of protecting your internal object, one, a const reference. Two, return a new variable. That involves constructing a new variable which takes time. The first way, it knows that you're not changing it, so it can just inline the direct call. So you'd get something like:
    Code:
    class thingie {
    public:
        const int& val() const { return m_val; }
    private:
        int m_val;
    };
    And any calls would resolve at compile time:
    Code:
    const int &ref = mythingie.val(); // const int &ref = mythingie.m_val
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  6. #6
    transcendental analytic kedaman's Avatar
    Join Date
    Mar 2000
    Location
    0x002F2EA8
    Posts
    7,221
    Originally posted by parksie
    The first way, it knows that you're not changing it, so it can just inline the direct call.
    It will inline it if you put inline (or forceinline in msvc, or autoinline) anyway, difference is that the function will be an accessor
    Use
    writing software in C++ is like driving rivets into steel beam with a toothpick.
    writing haskell makes your life easier:
    reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
    To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.

  7. #7
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    it returns a const reference because you are not supposed to write
    Counter c;
    ++++c;
    If the returned reference is const, this will result in a compiler error as it should be.
    Also, you are not supposed to write:
    ++c = ...;
    The result of both pre- and postfix increment/decrement operators are NOT L-values.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  8. #8
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    Maybe. I read that it is recommended by the standard that such things are not allowed, but it is not necessary. Anyway, I think it makes confusing code, so one shouldn't do it anyway (except you keda )
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  9. #9
    transcendental analytic kedaman's Avatar
    Join Date
    Mar 2000
    Location
    0x002F2EA8
    Posts
    7,221
    Code isn't confusing, it's the reader that is confused In fact you have to code so that it's obvious what you do, not why you do. For that you use comments(, if you're really bored that is)
    Use
    writing software in C++ is like driving rivets into steel beam with a toothpick.
    writing haskell makes your life easier:
    reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
    To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.

  10. #10
    Fanatic Member MoMad's Avatar
    Join Date
    Oct 2000
    Location
    Seattle, WA
    Posts
    625
    PHP Code:

    class Counter 

    public: 
     
    Counter(USHORT x) : itsVal(x) { } 
     ~
    Counter(){} 
     
    USHORT GetItsVal()const { return itsVal; } 
     
    void SetItsVal(USHORT x) {itsVal x; } 
     const 
    Counteroperator++ (); // prefix 
     
    const Counter operator++ (int); // postfix 
     
     
    private: 
     
    USHORT itsVal
    }; 

    // ...

    const Counteroperator++ () 

    ++
    itsVal
    return *
    this


    // ...
    void foo(Counterc) {
      
    printf("BEFORE:\t\t %d\n", (c++).GetItsVal() );
      
    printf("AFTER:   \t\t %d\n", (++c).getItsVal() ); 
      
    // will increment it then print the value, then increment again
    }

    // ...
    int main(void) {
      
    Counter c(10); // starts at 10

      
    foo(c);

      
    printf("\nFinal: \t\t %d\n"c.getItsVal() );

     return 
    1;

    Pay close attention to that code!!

    What happens is that, when the program starts, a new counter is created with value of 10. You call foo and what it does is:


    BEFORE: 10
    AFTER: 11
    FINAL: 12


    That is because the pre-increment opperator (++c) will increment the value to 11 then return a constant reference to itself (*this) after it pre-increments the internal value (10 to 11), but the post-increment (c++) will post-increment the internal value, and return the reference to itself, this will cause it to return first increment next.

    This code is valid in C++:

    PHP Code:

    (((++(((++c)++)++))++).getItsValue())++ 
    But it will not be very wise to do that because of the obvious.

    I think that the reason it returns a constant reference instead of just a reference is that they do not want that kind of code that i did. They do not want the "incremental chain" where you keep ++'ing!

    The constant is really unnecesary!! They are just trying to prevent crazy code such as: ((++(++((++(c++))++)))++).getItsValue() Try it out for yourself, take out the const and do some wild chain like that and see how good it is... that is the good thing about C++ it makes chaning things sooooo easy.

    -MoMad
    :MoMad:
    Nice Sig!

    http://go.to/momad/ Status: Not Ready

  11. #11
    Junior Member
    Join Date
    Dec 2001
    Location
    Melbourne - Australia
    Posts
    27

    all good now

    i came to the same conclusion as you moMad, that the only way to utilise the constant reference return is to stop people doing incremental chains. but now another problem, what about just a constant return type for a standard function, not an overload operator?

    eg:

    const int Test(const int variable)
    {
    return variable;
    }

    int main()
    {
    const int a=5;
    int b=Test(a);
    }

    In this example, does making the return type a const make any difference at all?

    bruce

  12. #12
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    Are you sure about that MoMad? By definition, your code should output this:
    BEFORE: 10
    AFTER: 12
    FINAL: 12

    This is because the value is incremented AFTER the first printf (postfix ++), and again BEFORE the second printf(prefix ++) (for a total of +2 before the second output = 12). If your code outputs the thing you wrote, there is some failure in it.

    Bruce: No it doesn't because it's only a copy: the return value is copied to b. const doesn't change anything here.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  13. #13
    Fanatic Member MoMad's Avatar
    Join Date
    Oct 2000
    Location
    Seattle, WA
    Posts
    625
    Sorry CornedBee, I made some changes to it because i realized it would not work because of the const so I forgot to change the output also.

    It was supposed to be: (without the const)

    PHP Code:
    class Counter 

    public: 
     
    Counter(USHORT x) : itsVal(x) { } 
     ~
    Counter(){} 
     
    USHORT GetItsVal()const { return itsVal; } 
     
    void SetItsVal(USHORT x) {itsVal x; } 
     
    Counteroperator++ (); // prefix 
     
    Counter operator++ (int); // postfix 
     
     
    private: 
     
    USHORT itsVal
    }; 

    // ...

    const Counteroperator++ () 

    ++
    itsVal
    return *
    this


    // ...
    void foo(Counterc) {
      
    printf("BEFORE:\t\t %d\n"c.GetItsVal() );
      
    printf("AFTER:   \t\t %d\n", ((++c)++).getItsVal() ); 
      
    // will increment it then print the value, then increment again
    }

    // ...
    int main(void) {
      
    Counter c(10); // starts at 10

      
    foo(c);

      
    printf("\nFinal: \t\t %d\n"c.getItsVal() );

     return 
    1;

    I made the first one post-increment to avoid the chain error with the constant! I should've cleaned up after myself, but thx for pointing that out.
    :MoMad:
    Nice Sig!

    http://go.to/momad/ Status: Not Ready

  14. #14
    Fanatic Member MoMad's Avatar
    Join Date
    Oct 2000
    Location
    Seattle, WA
    Posts
    625
    Hey Bruce,

    The const in your code just makes sure that you dont try to mess around with this variable you returned. But the thing is, it is absolutely unnecesary because that value being returned is a "copy" of the original and will not have any effect on the original wether you change it or not. A const reference is the same thing as a copy except a reference is 4bytes and a copy is n bytes where n is the size of the original!!

    So it always helps to use const reference or pointer instead of a full copy!!

    PHP Code:
    const int Test(const int variable
    {
      
    // The parameter AND the return type are already copies of the
      // original so it doesnt make sense to make them const 
      
    return variable


    int main() 

      const 
    int a=5
      
    int b=Test(a); // This has no effect on b.  Is like saying b = 5
      // infact you can try incrementing b here, it is valid!!

    Regards,
    MoMad
    :MoMad:
    Nice Sig!

    http://go.to/momad/ Status: Not Ready

  15. #15
    transcendental analytic kedaman's Avatar
    Join Date
    Mar 2000
    Location
    0x002F2EA8
    Posts
    7,221
    Hmm, i had a look myself too and it seems like it´s useless to increment the copy, if you want to have the copy incremented by one, a +1 would do, as ++ is meant to be for variables with scope, not parts of an expression, but assigning is just meaningless.
    All the cases i've been assigning incremented postfix expressions are pointers, and incremented pointers were dereferenced before the assignment (and it looks like *x++=...) thats why i thought it was legal.
    Use
    writing software in C++ is like driving rivets into steel beam with a toothpick.
    writing haskell makes your life easier:
    reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
    To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.

  16. #16
    Fanatic Member MoMad's Avatar
    Join Date
    Oct 2000
    Location
    Seattle, WA
    Posts
    625
    Hehehe, hmmm I see we still have C-purists <internal-joke> Yea I LOVE playing with pointers, its what makes C/C++ so different from ANY OTHER LANGUAGE!!

    You can make your own strcpy function, like:

    PHP Code:
    charstrcpychardest, const charsrc ) {
      while( *
    src )
         *
    dest++ = *src++;
      *
    dest 0;
      return 
    dest;

    See, As simple as said
    :MoMad:
    Nice Sig!

    http://go.to/momad/ Status: Not Ready

  17. #17
    transcendental analytic kedaman's Avatar
    Join Date
    Mar 2000
    Location
    0x002F2EA8
    Posts
    7,221
    no we don't At least i'm C++ purist, so doing pointer aritmetics doesnt bring me satisfaction. That however doesn't mean I don't so all the time, since it's the best way to save performance, and somehow it's become the standard way of iterating trough containers
    Use
    writing software in C++ is like driving rivets into steel beam with a toothpick.
    writing haskell makes your life easier:
    reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
    To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.

  18. #18
    Fanatic Member MoMad's Avatar
    Join Date
    Oct 2000
    Location
    Seattle, WA
    Posts
    625
    Also, it beats #including a whole library <string.h> just to use one simple function (strcpy). Instead, its better to inline it and/or make it a fastcall function BTW: C-Purist is also the same as C++-purist, it just doesnt make sense to have pluses and minuses in the same word (at least thats what i meant)

    -MoMad
    :MoMad:
    Nice Sig!

    http://go.to/momad/ Status: Not Ready

  19. #19
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    Originally posted by MoMad
    Also, it beats #including a whole library <string.h> just to use one simple function (strcpy). Instead, its better to inline it and/or make it a fastcall function BTW: C-Purist is also the same as C++-purist, it just doesnt make sense to have pluses and minuses in the same word (at least thats what i meant)

    -MoMad
    Well, since it's only definitions and constants all you lose is compile time...so there's no eventual benefit to doing that.
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  20. #20
    Fanatic Member MoMad's Avatar
    Join Date
    Oct 2000
    Location
    Seattle, WA
    Posts
    625
    Parksie, it will include the whole library into your project and compile it into your exe making it much larger and possibly slower. So yes, there are benefits
    :MoMad:
    Nice Sig!

    http://go.to/momad/ Status: Not Ready

  21. #21
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    Originally posted by MoMad
    Parksie, it will include the whole library into your project and compile it into your exe making it much larger and possibly slower. So yes, there are benefits
    But...but...but...it's all in a single .o file...

    The way the MS linker seems to work is that it can link to a minimum granularity of a single output file. Since most of the functions in the MS implementation of the CRT are all in their own files, it won't make much difference.

    PS: If anything, it'll be larger, but definitely not slower unless you inline it.

    PPS: With a string object, it'll most likely be inlined anyway
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  22. #22
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    strcpy in VC++ is an intrinsic function, which is the VC equivalent for C++ inlining.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  23. #23
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    I wonder how many of the extensions in VC++ are just there to make the CRT writers' lives easier

    Beware of some of the intrinsic functions though - a few are a bit buggy (c.f. Knowledge Base).
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

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