11

Is this the right way to return an object from a function?

Car getCar(string model, int year) {
   Car c(model, year);
   return c;
}

void displayCar(Car &car) {
   cout << car.getModel() << ", " << car.getYear() << endl;
}

displayCar(getCar("Honda", 1999));

I'm getting an error, "taking address of temporary". Should I use this way:

Car &getCar(string model, int year) {
   Car c(model, year);
   return c;
}

5 Answers 5

23

getCar returns a Car by value, which is correct.

You cannot pass that return value, which is a temporary object, into displayCar, because displayCar takes a Car&. You cannot bind a temporary to a non-const reference. You should change displayCar to take a const reference:

void displayCar(const Car& car) { }

Or, you can store the temporary in a local variable:

Car c = getCar("Honda", 1999);
displayCar(c);

But, it's better to have displayCar take a const reference since it doesn't modify the object.

Do not return a reference to the local Car variable.

Sign up to request clarification or add additional context in comments.

1 Comment

you can also store the temporary without invoking the copy constructor (which occurs in Car c = getCar(...) by using a reference to const: const Car &c = getCar(...), if you don't need to make changes thru c later on.
8

Your problem is:

void displayCar(Car &car) {
   cout << car.getModel() << ", " << car.getYear() << endl;
}

you should use a const reference:

void displayCar( const Car & car ) {
   cout << car.getModel() << ", " << car.getYear() << endl;
}

This function:

Car getCar(string model, int year) {
   Car c(model, year);
   return c;
}

is OK as it stands, but all it is doing is what the constructor does, so it is redundant. Passing a value back, rather than a reference, is the right thing to do for this type of function, however, The model parameter should be passed by const reference:

Car getCar( const string & model, int year) {

In general, for class types like string or Car, your default choice for a parameter should always be a const reference.

Comments

4

It is not safe to return a local variable's reference from a function.

So yes this is correct:

Car getCar(string model, int year) {
   Car c(model, year);
   return c;
}

7 Comments

Hmm, I need something like a factory function which will create an object and return it back.
Many (most?) compilers optimize return Car(model, year) so that no additional copy needs to be made, so I'd get rid of the explicit local variable.
@Steven: Many (most?) compilers implement named return value optimization (NRVO) as well, so there's generally no difference.
@pocoa: You could also use dynamic memory for all of this by allocating a new instance and returning by pointer. I would recommend using the appropriate sort of smart pointer, to avoid leaks.
@James: You may be right. Last I checked, named values were less likely to be optimized.
|
2

Yes, it is definitely not safe to return a reference or a pointer to a temporary object. When it expires (ie, when the function getCar exits), you'll left with what is technical known as a "dangling pointer".

However, if you're keen on reducing copy operations on an object, you should check out C++0x's "Move semantics". It is a relatively new concept, but I'm sure it'll become main-stream soon enough. GCC 4.4 upwards supports C++0x (use the compiler option -std=c++0x to enable).

Comments

0

Even better:

Car getCar(string model, int year) { 
      return Car(model, year);  
}

2 Comments

Exactly what I meant by "copy operations" in my answer. Although currently this is the standard solution it is much more an expensive operation than just returning an address.
@themoondothshine: Most compilers (all I know of) will perform RVO here, so it is a really cheap operation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.