Возврат локального объекта из функции - PullRequest
10 голосов
/ 02 апреля 2010

Это правильный способ вернуть объект из функции?

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

Ответы [ 5 ]

23 голосов
/ 02 апреля 2010

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

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

void displayCar(const Car& car) { }

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

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

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

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

8 голосов
/ 02 апреля 2010

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

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

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

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

Эта функция:

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

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

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

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

4 голосов
/ 02 апреля 2010

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

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

Car getCar(string model, int year) {
   Car c(model, year);
   return c;
}
2 голосов
/ 02 апреля 2010

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

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

0 голосов
/ 02 апреля 2010

Еще лучше:

Car getCar(string model, int year) { 
      return Car(model, year);  
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...