Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++: Returning by value with a reference

Tags:

c++

I am seeking clarification of what exactly happens when one returns a reference to an object in a function with a return type of that object.

Consider the following function:

CObject getObject() {
    CObject localObject;
    CObject &objectRef(localObject);
    return objectRef;
}

It is my understanding that this function will return a copy of "localObject", as opposed to returning the reference to "localObject". Is this correct? Is it essentially creating and returning a new object with localObject as the constructor parameter? E.g.,

CObject newObject(localObject);
like image 242
Ludus Avatar asked Mar 13 '23 03:03

Ludus


2 Answers

It will return a copy of your object. However, be careful if you change your function declaration to return a reference, your code will result in Undefined Behavior.

Example:

class CObject{
    public:
    CObject(){std::cout << "cosntructing ";}
    CObject(const CObject& other){std::cout << "copying ";}
};

CObject getObject(){
    CObject localObject;
    CObject &objectRef(localObject);
    return objectRef;
}

int main(){
   auto result =  getObject();
}

This will result in:

cosntructing copying

Note: you may not get the same results if your compiler is fully optimizing the code due to RVO. So turn off all optimization and try. As @Caduchon stated that even with no optimization, results can change due to copy-elision.


Example of the function with undefined behavior:

CObject& getObject() {
    CObject localObject;
    CObject &objectRef(localObject);
    return objectRef;
}
like image 105
Humam Helfawi Avatar answered Mar 14 '23 17:03

Humam Helfawi


You are correct that it is not returning a reference to the local object. In terms of what actually is returned, the answer is a little bit more subtle. Due to something called return value optimisation, the compiler will actually only create one instance of CObject as a result of calling the function. It is an optimisation trick that basically means the original localObject is constructed in such a way as to be directly usable by the calling function - so no copy construction is necessary upon the return of the call.

like image 25
Smeeheey Avatar answered Mar 14 '23 17:03

Smeeheey