CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 3 123 LastLast
Results 1 to 15 of 42
  1. #1
    Join Date
    Oct 2002
    Location
    Boston
    Posts
    40

    Default Initialization of reference variables in methods

    How do I initialize references in my method

    BOOL GetSelectedItem(INDEX_DATA& pIndex,
    int& nSelItem =-1/*???*/);

    Is it possible. I know I am doing wrong, because Compiler tells

  2. #2
    Join Date
    Jun 2002
    Posts
    224
    Code:
    void foo( const int& a_i = -1 )
    {
      //...
    }
    I hope it helps.

    Regards,
    ZDF

    What is good is twice as good if it's simple.
    "Make it simple" is a complex task.

  3. #3
    Join Date
    Aug 2002
    Location
    Madrid
    Posts
    4,588
    Well, yes that works, but obviously you won't be able to change a_i, which might defeat the point of passing by reference.

    But there is no solution to this (as far as I can imagine), since the reference operator implies that you are actually passing a dereferenced pointer to an int. This means that a_i has to be somewhere in memory as opposed to a constant like -1.

    The reason it works with const int& a_i = -1 is that the compiler will allocate a static variable for -1 and &a_i will point to that one. So it's the same as writing :
    Code:
    const static minusone = -1;
    
    void foo(const int &i = minusone)
    { 
      // code
    }
    Last edited by Yves M; October 31st, 2002 at 05:36 PM.

  4. #4
    Join Date
    Sep 2002
    Location
    Singapore
    Posts
    673
    Originally posted by Yves M
    Well, yes that works, but obviously you won't be able to change a_i, which might defeat the point of passing by reference.

    But there is no solution to this (as far as I can imagine), since the reference operator implies that you are actually passing a dereferenced pointer to an int. This means that a_i has to be somewhere in memory as opposed to a constant like -1.

    The reason it works with const int& a_i = -1 is that the compiler will allocate a static variable for -1 and &a_i will point to that one. So it's the same as writing :
    Code:
    const static minusone = -1;
    
    void foo(const int &i = minusone)
    { 
      // code
    }
    The reason for passing reference in such case is to eliminate the need to write a copy constructor (if that needs to be). The const keyword is to tell the user of your function that the object he passed, wouldn't get modifed.

  5. #5
    Join Date
    Aug 2002
    Location
    Madrid
    Posts
    4,588
    Yes, I know I was referring to the line of code agni gave :
    BOOL GetSelectedItem(INDEX_DATA& pIndex, int& nSelItem =-1);
    If he didn't want to modify nSelItem then it would be easier to pass by value rather than try this default initialisation.

  6. #6
    Join Date
    May 2000
    Location
    KY, USA
    Posts
    18,652

    Re: Default Initialization of reference variables in methods

    Originally posted by agni256
    BOOL GetSelectedItem(INDEX_DATA& pIndex,
    int& nSelItem =-1/*???*/);
    Besides the problem itself just a note...why do you want to pass a reference to a POD, in this case an integer...

    There is no advantage of passing POD's by reference rather than by value. I mean if the above function is just a sample to show the problem it is okay but if this is really what you are looking for than I would just answer...
    Code:
    BOOL GetSelectedItem(INDEX_DATA& pIndex, int nSelItem =-1);

  7. #7
    Join Date
    Aug 2002
    Location
    Madrid
    Posts
    4,588
    Well, one use of passing by reference is to allow the function to modify the variable passed (so that the changes are reflected in the caller's scope) and make it clear that that variable is not optional. If you passed by pointer, the caller could always pass NULL and that might not make sense.

    For the original question, it does not work either when you are passing a pointer to a variable, unless you specify NULL or make it a pointer to a global variable.

    For example, this works:
    Code:
    int minusone;
    
    void func(int *p = &minusone)
    {
      int i;
    
      i = *p;
    }
    
    int main(int argc, char* argv[])
    {
      minusone = -1;
      func();
      return 0;
    }
    But of course this can be a source of endless errors, especially if you modify *p inside func.
    Get this small utility to do basic syntax highlighting in vBulletin forums (like Codeguru) easily.
    Supports C++ and VB out of the box, but can be configured for other languages.

  8. #8
    Join Date
    Mar 2002
    Location
    California
    Posts
    1,582
    Yes, you can use a global as the default parameter. The problem with that is if the parameter ever changes, you could easily get different behaviors with different, even consecutive, calls to the method. This could bugs that would be difficult to find.

    Edit: Which is, umm, what Yves just said.

    Jeff
    Last edited by jfaust; November 1st, 2002 at 09:31 AM.

  9. #9
    Join Date
    May 2000
    Location
    KY, USA
    Posts
    18,652
    Originally posted by Yves M
    Well, one use of passing by reference is to allow the function to modify the variable passed (so that the changes are reflected in the caller's scope) and make it clear that that variable is not optional.
    Well...yes you are right. I think I did not have enough coffee yet... I usually use references only if the function does not change it thus I just const-references...

    I think I got so used to it, that I did not think enough...sorry about that...

  10. #10
    Join Date
    Aug 2002
    Location
    Madrid
    Posts
    4,588
    Passing by reference to allow changing the variable is a pretty thorny issue anyways. Here is what Stroustrup says about it (section 5.5 p99).
    A reference can be used to specify a function argument so that the function can change the value of an object passed to it. For example:
    Code:
    void increment(int &aa) {aa++;}
    
    void f()
    {
       int x = 1;
       increment(x);     // x = 2
    }
    ...
    To keep a program readable, it is often best to avoid functions that modify their arguments.
    Get this small utility to do basic syntax highlighting in vBulletin forums (like Codeguru) easily.
    Supports C++ and VB out of the box, but can be configured for other languages.

  11. #11
    Join Date
    May 2000
    Location
    KY, USA
    Posts
    18,652
    Originally posted by Yves M
    To keep a program readable, it is often best to avoid functions that modify their arguments.
    Well...basically that is the reason why I pass pointers while functions modify their arguments and const-references otherwise...

  12. #12
    Join Date
    Mar 2002
    Location
    California
    Posts
    1,582
    Possibly of interest:

    Parameters are often passed in as output parameters when the method needs to set more than one value. However, it is possible for methods to return multiple values. The quick answer is to use a struct, but there are better ways in which you don't have to declare a new struct. std::pair works great for returning two values, possibly the value you are interested in as well as an error condition. For more than two values, there is boost::tuple, which can be found at boost.

    For arguments that are both input and output, well... ich.

    Jeff

  13. #13
    Join Date
    Aug 2002
    Location
    Madrid
    Posts
    4,588
    Yeah, well, I do use non-const references for functions with descriptive names, like KeyPlusPlus(KeyType &key) for example. But it's true that it should generally be avoided since it's not clear to the caller that his parameter can be modified and that he can't pass a constant :/

    As for multiple return values... Hum... I would still prefer using non-const references, but then I'll document the function well.

  14. #14
    Join Date
    Mar 2002
    Location
    California
    Posts
    1,582
    I would still prefer using non-const references, but then I'll document the function well.
    I understand. It's a pretty big change from standard practice. However, after adjusting to it, all intentions are clear without extra documentation. I prefer policies that can be enforced by the compiler rather than relying on source documentation.

    Jeff

  15. #15
    Join Date
    Oct 2002
    Location
    Boston
    Posts
    40
    I generally use references if I need to pass back multiple results.
    I restrict the return value to BOOL to know whether method was successful.

    In the following code:
    BOOL DisplayField(int nRow=0, int nCol=0, CString strType="C",
    CString strValue="", CString& strDispValue=CString(""),

    I could intialize and change the value of stDispValue.
    Yves may be correct here that complier needs some memory
    to point to.
    Can we say then its only primitives that may not work?
    Intializing with Objects will, as they have memory to point to..

Page 1 of 3 123 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