CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 13 of 13

Thread: const reference

  1. #1
    Join Date
    Sep 2003
    Posts
    815

    const reference

    Hi,

    I was wondering what is the meaning of a function returning a const reference?

    for example I have a function that defined like this:

    const int& getNum() const;

    how do I call this function, is
    int i = getNum();

    ok?

    Thanks
    Avi123

  2. #2
    Join Date
    May 2005
    Posts
    4,954

    Re: const reference

    Quote Originally Posted by avi123
    Hi,

    I was wondering what is the meaning of a function returning a const reference?

    for example I have a function that defined like this:

    const int& getNum() const;

    how do I call this function, is
    int i = getNum();

    ok?

    Thanks
    Avi123
    the answer is yes,

    • Code:
        int num  =  getNum(); // ok.
        // num can be modified here
        num = 123; // ok
    • Code:
      int &num1=  getNum(); // not ok
    • Code:
        const int &num2=  getNum(); // ok
        // but here num2 cannot be modified!!!
        num2 = 123; // not ok  


    Cheers
    If a post helped you dont forget to "Rate This Post"

    My Article: Capturing Windows Regardless of Their Z-Order

    Cheers

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

    Re: const reference

    Normally you would not return an int by const reference unless done through a template (thus you are handling all types).

    However there is an advantage of returning a full object by const reference because then it does not need to copy the object. (And the object might not be copyable anyway).

  4. #4
    Join Date
    Sep 2003
    Posts
    815

    Re: const reference

    Quote Originally Posted by golanshahar
    the answer is yes,

    • Code:
        int num  =  getNum(); // ok.
        // num can be modified here
        num = 123; // ok
    • Code:
      int &num1=  getNum(); // not ok
    • Code:
        const int &num2=  getNum(); // ok
        // but here num2 cannot be modified!!!
        num2 = 123; // not ok  


    Cheers
    about the first answer, I don't understand if I use int num = getNum() , does it mean that I canceled the const?

    another thing abuot the first answer, what if I get out of the scope of the int num that got return value of GetNum, does it mean that the value getNum has returned is now corrupted? (since it returned a reference)?

    Thanks again
    Avi123

  5. #5
    Join Date
    Sep 2003
    Posts
    815

    Re: const reference

    Quote Originally Posted by NMTop40
    Normally you would not return an int by const reference unless done through a template (thus you are handling all types).

    However there is an advantage of returning a full object by const reference because then it does not need to copy the object. (And the object might not be copyable anyway).
    Hi,

    I'm not really returning an int but a reference to a struct I defined, it was just a simple example

    The thing is that I don't really understand the meaing of a const reference return value, can you pls explain it to me?

    Thanks again
    Avi123

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

    Re: const reference

    Quote Originally Posted by avi123
    Hi,

    I'm not really returning an int but a reference to a struct I defined, it was just a simple example

    The thing is that I don't really understand the meaing of a const reference return value, can you pls explain it to me?

    Thanks again
    Avi123
    A const reference is basically just implemented as a pointer to the structure.
    But a const reference is used like a value (because it is a reference).
    Morevoer, since it is const, the user cannot (except if he uses a const_cast) modify the structure via this reference.

    Finally returning const references is faster then returning values, and is equivalent with a restriction:
    The lifetime of the const reference returned is the lifetime of the object returned, so, for example, you must not return a local variable by const-reference, but, in a method, you can return a const-reference to a member variable of the class (or any data which has the lifetime of the object, such as std::vector:perator[]const does).
    Of course, the class's user must know that this const-reference has only the lifetime of the class's object, and may copy the value if he wants to save this value after the object destruction.
    "inherit to be reused by code that uses the base class, not to reuse base class code", Sutter and Alexandrescu, C++ Coding Standards.
    Club of lovers of the C++ typecasts cute syntax: Only recorded member.

    Out of memory happens! Handle it properly!
    Say no to g_new()!

  7. #7
    Join Date
    Sep 2005
    Location
    London
    Posts
    28

    Re: const reference

    A reference is very similar to a pointer - it refers to another object rather than 'being' that object.

    When you return a const reference, you're saving the time and effort for the compiler to copy the object - consider this:

    Code:
    struct Foo
    {
      int a[10000];
    };
    
    Foo Function1()
    {
        Foo bar;
        // fill in bar here
        return bar;
    }
    
    const Foo& Function2()
    {
       static Foo bar; // See note below!
       // prepares bar here (again, see note)
       return bar;
    }
    In Function1, the compiler creates a 'Foo' on the stack (all ~40k of it!), then your code fills it in. When you return it by value, the compiler must copy it to the caller! Unlike say a float, or an int (which generally fits into a processor register) this takes some time. (there's also all sorts of extra things that could happen in the copy constructor or operator=() for the class, but I won't go into that here). In most cases, you'll want to avoid code like Function1().

    In Function2, a reference to an existing Foo object is returned. This is just like a pointer, so is quick. Of course, you wouldn't necessarily want callers to Foo to be able to modify the object you're making a reference to, hence the const reference.

    Note that in this trivial example I've had to use a static Foo object - this is generally bad practice - but reinforces an important thing you have to think about when returning references (and indeed pointers) - the lifetime of the object you return a reference to must equal or exceed that of the reference(/pointer) you return! This is made easier when you're using objects: an object's member function could return a const reference to one of its member variables as a way of implementing an accessor:-

    Code:
    class Foo
    {
    private:
        Baz mBazObject; // a 'large' object representing some internal state
    public:
        // Accessors and mutators:
        const Baz& GetBaz() const { return mBazObject; }
        void SetBaz(const Baz& iBaz) { mBazObject = iBaz; }
    };
    Edit: one important thing to note is in order to reap the benefits of using references you'll have to declare your variables as references too:

    Code:
    const Baz& bazObjectRef = foo.GetBaz(); // Good
    Baz bazObject = foo.GetBaz(); // Works, but takes a copy of the baz object
    For more practical purposes the const reference is utterly equivalent to the object itself - unless you want to change it.

    Using const references is a Good Thing - but it will also expose lots of issues in your code if you haven't been const correct throughout - something I really recommend you do both from an optimisation point of view, and a sheer design-by-contract idea.
    Last edited by TheMoog; September 19th, 2005 at 11:22 AM. Reason: Missed out an important point!
    Matt Godbolt
    Developer, ProFactor Software
    IncludeManager - a #include graph generator | StyleManager - a VS.NET plugin C/C++ code beautifier

  8. #8
    Join Date
    Sep 2003
    Posts
    815

    Re: const reference

    Quote Originally Posted by TheMoog
    Edit: one important thing to note is in order to reap the benefits of using references you'll have to declare your variables as references too:

    Code:
    const Baz& bazObjectRef = foo.GetBaz(); // Good
    Baz bazObject = foo.GetBaz(); // Works, but takes a copy of the baz object
    For more practical purposes the const reference is utterly equivalent to the object itself - unless you want to change it.

    Using const references is a Good Thing - but it will also expose lots of issues in your code if you haven't been const correct throughout - something I really recommend you do both from an optimisation point of view, and a sheer design-by-contract idea.

    what if I use this:
    Baz bazObject = foo.GetBaz(); // Works, but takes a copy of the baz object

    I understand it really copies the object, but does it have any pthere problems? for example what if I change the local bazObject does it effect the member somehow? and when I get out of scope of the local bazObject?

    Thanks
    avi123

  9. #9
    Join Date
    Sep 2005
    Location
    London
    Posts
    28

    Re: const reference

    Quote Originally Posted by avi123
    what if I use this:
    Baz bazObject = foo.GetBaz(); // Works, but takes a copy of the baz object

    I understand it really copies the object, but does it have any pthere problems? for example what if I change the local bazObject does it effect the member somehow? and when I get out of scope of the local bazObject?
    There will be no problems at all using this - you've taken a copy of the object, and so modifying 'bazObject' will NOT alter the original. Similarly when bazObject goes out of scope, the original will also not be affected.

    For completeness: This is only true if the 'Baz' object itself has proper copy semantics -- if Baz holds a pointer to another object (say, Bob) which isn't 'deep copied', then when you take a copy of the Baz object you're still only taking a copy of a reference to the Bob -- modifying Baz might then alter the original Bob referred to by Baz. All rather complex sounding, I can probably rustle up an example if that's confusing!
    Matt Godbolt
    Developer, ProFactor Software
    IncludeManager - a #include graph generator | StyleManager - a VS.NET plugin C/C++ code beautifier

  10. #10
    Join Date
    Sep 2003
    Posts
    815

    Re: const reference

    Quote Originally Posted by TheMoog
    There will be no problems at all using this - you've taken a copy of the object, and so modifying 'bazObject' will NOT alter the original. Similarly when bazObject goes out of scope, the original will also not be affected.

    For completeness: This is only true if the 'Baz' object itself has proper copy semantics -- if Baz holds a pointer to another object (say, Bob) which isn't 'deep copied', then when you take a copy of the Baz object you're still only taking a copy of a reference to the Bob -- modifying Baz might then alter the original Bob referred to by Baz. All rather complex sounding, I can probably rustle up an example if that's confusing!
    and if I have a copy constructor will it be called when I use:
    Baz bazObject = foo.GetBaz(); // Works, but takes a copy of the baz object


    Thanks again
    avi123

  11. #11
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470

    Re: const reference

    Quote Originally Posted by avi123
    and if I have a copy constructor will it be called when I use:
    Baz bazObject = foo.GetBaz(); // Works, but takes a copy of the baz object


    Thanks again
    avi123
    Yes.
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
    --
    Sutter and Alexandrescu, C++ Coding Standards

    Programs must be written for people to read, and only incidentally for machines to execute.

    --
    Harold Abelson and Gerald Jay Sussman

    The cheapest, fastest and most reliable components of a computer system are those that aren't there.
    -- Gordon Bell


  12. #12
    Join Date
    Sep 2003
    Posts
    815

    Re: const reference

    Quote Originally Posted by Graham
    Yes.

    Then what is the probelm using it?
    I mean besdie efficency...

    Thanks
    avi123

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

    Re: const reference

    It is just less efficient (for objects having a heavy copy construction) than const Baz &bazObject = foo.GetBaz();, but has no more problem.

    Moreover Baz bazObject = foo.GetBaz(); has an efficiency very near than return by value, but is a bit less efficient when dealing with very small objects such as int.

    Finally, you should return an object by const-reference instead of returning it by value if:
    • The lifetime of the object is sufficient (for example if the referenced object at the same lifetime than the object whose method is called).
    • And the object is not too small (for example 4 bytes values are fastly returned by value).
      This slowing factor is not very important.

    If the type is templatized, you cannot know if it is small or big, so in the doubt you should assume that it is big, and return by const-reference.
    "inherit to be reused by code that uses the base class, not to reuse base class code", Sutter and Alexandrescu, C++ Coding Standards.
    Club of lovers of the C++ typecasts cute syntax: Only recorded member.

    Out of memory happens! Handle it properly!
    Say no to g_new()!

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