Действительно ли это - правильный способ возвратить объект из функции?
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;
}
getCar
возвращает Car
по значению, что является правильным.
Вы не можете передать это возвращаемое значение, которое является временным объектом, в displayCar
, потому что displayCar
принимает Car &
. Вы не можете привязать временную ссылку к неконстантной ссылке. Вы должны изменить displayCar
, чтобы он принимал константную ссылку:
void displayCar(const Car& car) { }
Или вы можете сохранить временное значение в локальной переменной:
Car c = getCar("Honda", 1999);
displayCar(c);
Но лучше, чтобы displayCar
принимал константу ссылка, поскольку она не изменяет объект.
Не возвращать ссылку на локальную переменную Car
.
Возвращать ссылку на локальную переменную из функции небезопасно.
Итак, да, это правильно:
Car getCar(string model, int year) {
Car c(model, year);
return c;
}
Ваша проблема:
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, ваш выбор по умолчанию для параметра всегда должен быть константной ссылкой.
Да, возвращать ссылку или указатель на временный объект определенно небезопасно. Когда срок его действия истечет (т.е. когда функция getCar
выйдет), вы останетесь с тем, что технически известно как "висящий указатель".
Однако если вы заинтересованы в сокращении операций копирования объекта, вам следует ознакомиться с "семантикой перемещения" C++0x. Это относительно новая концепция, но я уверен, что скоро она станет основной. GCC 4.4 и выше поддерживает C++0x (используйте опцию компилятора -std=c++0x
для включения).
Еще лучше:
Car getCar(string model, int year) {
return Car(model, year);
}