Harold Serrano

View Original

C++ tip 14: Don't return a reference when you must return an object

Consider the following function:


const Point multiply(const Point& p);

The function above returns an object by value. From the previous tip, you know that you should not pass an object by value, but instead by reference.

Passing by reference means passing a reference to an object that already exist. Thus, if you want to return a reference in a function, it means that you must create that object in the function.

You know that a function can create a new object in two ways: On the stack or the heap.

For example, the following function creates an object on the stack:


//passing by reference with object created on stack
const Point& multiply(const Point& p){
Point point();
//... Do multiplication
return point;
}

The problem with this is that when you exit the function, all local objects are destroyed, so whatever reference you think you are returning actually was destroyed upon exit.

The other way a function can create an object is on the heap. This is done as follows:


//passing by reference with object created on heap
const Point& multiply(const Point& p){
Point *point=new Point();
//... Do multiplication
return *point;
}

The problem with this is that you may end up with memory leaks. Who is going to take care of calling a delete on the created object?

In his book Effective C++, Scott Meyers suggest the following:

Never return a pointer or a reference to a local stack object or a reference to a heap-allocated object

Scott states that the right way to write a function that must return a new object is to have that function return a new object as such:


//This function returns a new object, not a reference to the object
const Point multiply(const Point& p){
Point point();
//... Do multiplication
return point;
}

Now, you may say "aren't we creating a local object which will be destroyed upon exiting the function". Well, yes. We are creating a local object. However, during the return the compiler invokes the copy constructor of Point. Thus the object gets returned.

Sign up to my newsletter below and receive game engine development and c++ tips.