Возврат локального объекта из функции

Правильно ли он возвращает объект из функции?

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));

Я получаю сообщение об ошибке "с адресом временного". Должен ли я использовать этот способ:

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

Ответ 1

getCar возвращает значение Car по значению, которое является правильным.

Вы не можете передать это возвращаемое значение, являющееся временным объектом, в displayCar, потому что displayCar занимает Car&. Вы не можете привязать временную ссылку к неконстантной ссылке. Вы должны изменить displayCar, чтобы получить ссылку на константу:

void displayCar(const Car& car) { }

Или вы можете сохранить временную локальную переменную:

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

Но лучше иметь displayCar взять ссылку на константу, поскольку она не изменяет объект.

Не возвращать ссылку на локальную переменную Car.

Ответ 2

Ваша проблема:

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

вы должны использовать ссылку const:

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

Эта функция:

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

в порядке, но все, что он делает, это то, что делает конструктор, поэтому он избыточен. Передача значения назад, а не ссылки, является правильным решением для этого типа функции. Однако параметр модели должен быть передан с помощью ссылки const:

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

В общем случае для типов классов, таких как string или Car, ваш выбор по умолчанию для параметра всегда должен быть ссылкой const.

Ответ 3

Неправильно возвращать ссылку на локальную переменную из функции.

Итак, да, это правильно:

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

Ответ 4

Да, небезопасно возвращать ссылку или указатель на временный объект. Когда он истечет (т.е. Когда функция getCar завершается), вы останетесь с тем, что известно как "оборванный указатель".

Однако, если вы заинтересованы в сокращении операций копирования на объекте, вы должны проверить С++ 0x "Переместить семантику". Это относительно новая концепция, но я уверен, что она скоро станет основным потоком. GCC 4.4 поддерживает С++ 0x (используйте параметр компилятора -std=c++0x для включения).

Ответ 5

Еще лучше:

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