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

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

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;
}
10
задан pocoa 2 April 2010 в 16:50
поделиться

5 ответов

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

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

void displayCar(const Car& car) { }

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

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

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

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

23
ответ дан 3 December 2019 в 14:06
поделиться

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

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

Car getCar(string model, int year) {
   Car c(model, year);
   return c;
}
4
ответ дан 3 December 2019 в 14:06
поделиться

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

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, ваш выбор по умолчанию для параметра всегда должен быть константной ссылкой.

8
ответ дан 3 December 2019 в 14:06
поделиться

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

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

2
ответ дан 3 December 2019 в 14:06
поделиться

Еще лучше:

Car getCar(string model, int year) { 
      return Car(model, year);  
}
0
ответ дан 3 December 2019 в 14:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: