CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 26
  1. #1
    Join Date
    Oct 2007
    Location
    Scotland
    Posts
    137

    returning objects by reference

    hi, I have a class with overloaded operators that return references to new objects instead of the objects themselves. the problem is when I try to chain together a sequence of operations it gives wrong results.

    CPoint2d<int> a(100, 100);
    CPoint2d<int> b(150, 150);
    CPoint2d<int> c(200, 200);

    this works:
    CPoint2d<int> d = a + b;

    this dosn't:
    CPoint2d<int> d = a + (b + c);

    the only difference I can see is that (b + c) will be evaluated first and return a reference to a's + operator. here's what the function looks like:

    template <class T>
    CPoint2d<T>& CPoint2d:perator +(const CPoint2d<T> &p) const
    {
    return CPoint2d<T>(x + p.x, y + p.y);
    }

    it works if I return by value.

  2. #2
    Join Date
    Apr 1999
    Posts
    27,449

    Re: returning objects by reference

    Quote Originally Posted by staticVoid
    hi, I have a class with overloaded operators that return references to new objects instead of the objects themselves.
    Code:
    template <class T>
    CPoint2d<T>& CPoint2d::operator +(const CPoint2d<T> &p) const
    {
       return CPoint2d<T>(x + p.x, y + p.y);
    }
    You are returning a reference to a local object. When the function returns, that object is gone. So what happens to the reference returned? It's gone too. Therefore that code leads to undefined behaviour.

    When you return a reference, you must return a reference to an object that will outlast the lifetime of the function. This means that you can only return references to class members, globals, statics, or dynamically created objects, not locally declared objects.

    Regards,

    Paul McKenzie

  3. #3
    Join Date
    Jul 2002
    Location
    Portsmouth. United Kingdom
    Posts
    2,727

    Re: returning objects by reference

    Quote Originally Posted by staticVoid
    it works if I return by value.
    That's the usual way to write operator +

    Operator += returns a reference to the class instance and operator + is often written in terms of operator +=

  4. #4
    Join Date
    Oct 2007
    Location
    Scotland
    Posts
    137

    Re: returning objects by reference

    why then does it work when I initialze a variable with it eg.

    CPoint2d<int> d = (a + b)

    but not:

    CPoint2d<int> d;
    d = (a + b);

  5. #5
    Join Date
    Jul 2002
    Location
    Portsmouth. United Kingdom
    Posts
    2,727

    Re: returning objects by reference

    This is the crib sheet I use to remind myself about operator overloading.

    Member functions.
    &operator * ()
    *operator -> ()
    &operator ++ () Return *this
    const operator ++ (int) Return original by value
    &operator -- () Return *this
    const operator -- (int) Return original by value
    &operator += (int rhs) Return *this
    &operator -= (int rhs) Return *this



    Friend functions
    bool operator == (const &lhs, const &rhs)
    bool operator != (const &lhs, const &rhs)
    bool operator < (const &lhs, const &rhs)
    operator + (const &lhs, const &rhs) Return by value
    operator - (const &lhs, const &rhs) Return by value


    Implement + and - operators in terms of += and -=

  6. #6
    Join Date
    Jul 2002
    Location
    Portsmouth. United Kingdom
    Posts
    2,727

    Re: returning objects by reference

    Quote Originally Posted by staticVoid
    why then does it work when I initialze a variable with it eg.
    Undefined behaviour + luck.

  7. #7
    Join Date
    Oct 2007
    Location
    Scotland
    Posts
    137

    Re: returning objects by reference

    just shows you - don't always believe what you read - !that when you return a refernce to local object it copy's the object from the stack to the heap and the reference will still be valid.

  8. #8
    Join Date
    Jul 2002
    Location
    Portsmouth. United Kingdom
    Posts
    2,727

    Re: returning objects by reference

    When you return a reference to something it's often because you don't want to have the overhead of a copy or you want to modify the referred variable.

  9. #9
    Join Date
    Apr 1999
    Posts
    27,449

    Re: returning objects by reference

    Quote Originally Posted by staticVoid
    just shows you - don't always believe what you read - !that when you return a refernce to local object it copy's the object from the stack to the heap and the reference will still be valid.
    What book states that? That makes no sense if the object is gone. When a function returns, local objects are destroyed. So what can a reference be referring to if the local object is gone? References need live objects to be referred to. You can't transfer a reference from one object to another.

    Regards,

    Paul McKenzie

  10. #10
    Join Date
    Oct 2007
    Location
    Scotland
    Posts
    137

    Re: returning objects by reference

    Quote Originally Posted by Paul McKenzie
    What book states that? That makes no sense if the object is gone. When a function returns, local objects are destroyed. So what can a reference be referring to if the local object is gone? References need live objects to be referred to. You can't transfer a reference from one object to another.

    Regards,

    Paul McKenzie

    I can't remember where I read it but it wasn't a book, it was some article on the net. so how to people get around returning by value, instead of using RVO like:
    Code:
    template <class T>
    static void CPoint2d<T>::add(const CPoint2d<T> &a, const CPoint2d<T> &b, CPoint2d<T> &result)
    {
       result.x = a.x + b.x;
       result.y = a.y + b.y;
    }
    or is this^ the best way to do it? I know in small cases its probaly ok, like CPoint2d<int> to return by value but what if you had say:
    Code:
    class Big64
    {
    public:
       __int64 rg[10000000];
    };
    
    CPoint2d<Big64> a, b, c;
    
    a = b + c;
    would that not have a significant reduction in speed?

  11. #11
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: returning objects by reference

    That is the use of an out parameter, not returning a reference to a local variable. Since the argument passed exists in the caller, it continues to exist when control leaves the function, unlike the local variable that is destroyed.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  12. #12
    Join Date
    Oct 2007
    Location
    Scotland
    Posts
    137

    Re: returning objects by reference

    yes - Return Value Optimization, but what are the benefits of using operator overload if (when returning by value) it is slower than using this method? besides being able to do -> a = b + c / d * e;

  13. #13
    Join Date
    Apr 1999
    Posts
    27,449

    Re: returning objects by reference

    Quote Originally Posted by staticVoid
    I can't remember where I read it but it wasn't a book, it was some article on the net. so how to people get around returning by value,
    In the case of a = b + c, you are returning a new value and assigning it to "a", erasing the old value of whatever "a" had. What if "a" contained members that were dynamically allocated? How would you get around not destroying the old contents and replacing it with the new contents? It must be a live new object that is being assigned, the emphasis on live. A reference is bound to one object, and is bound to it for life. If the life of the object ceases to exist, the reference ceases to exist.
    would that not have a significant reduction in speed?
    I don't know -- time it and find out if it is significantly slower.

    Also, as pointed out, you implement operator + in terms of operator +=. The operator += returns a reference to the existing object. That is where you may be confused.
    Code:
    SomeObject& operator +=(const SomeObject& rhs)
    {
       //... whatever you need to do to add 
       return *this;
    }
    Then operator + is implemented in terms of +=
    Code:
    SomeObject operator +(const SomeObject& obj1, const SomeObject& obj2)
    {
        SomeObject temp = obj1;
        return temp += obj2;
    }
    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; May 12th, 2008 at 12:42 PM.

  14. #14
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: returning objects by reference

    but what are the benefits of using operator overload if (when returning by value) it is slower than using this method? besides being able to do -> a = b + c / d * e;
    That's the only benefit: syntactic sugar. You can check out the GMP library; they have managed to avoid this problem of unnecessary temporaries in some cases by the use of expression templates.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  15. #15
    Join Date
    Apr 1999
    Posts
    27,449

    Re: returning objects by reference

    Quote Originally Posted by staticVoid
    yes - Return Value Optimization, but what are the benefits of using operator overload if (when returning by value) it is slower
    How much slower? Is it really slower? What if the reduction in speed (if any) is so insignificant it makes no difference whatsoever?

    Regards,

    Paul McKenzie

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