Возврат локального объекта из функции
Правильно ли он возвращает объект из функции?
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);
}