Храните S как поле ForInterview и возвращайте ссылку на это поле. Локальный S уничтожается при выходе из get_ref, поэтому возвращённая ссылка на него сразу становится висячей.
Методы рефакторинга, возвращающие ссылки на временные объекты
Храните S как поле ForInterview и возвращайте ссылку на это поле. Локальный S уничтожается при выходе из get_ref, поэтому возвращённая ссылка на него сразу становится висячей.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
В классе ForInterview функции get_ref() в настоящее время возвращают ссылку на локально созданный экземпляр, что приводит к висячей ссылке. Переделайте реализацию так, чтобы возвращаемая ссылка оставалась действительной после выхода из функции.
class ForInterview {
public:
struct S {
int x = 1;
};
const S& get_ref() const {
S s;
return s;
}
S& get_ref() {
S s;
return s;
}
void run() {
const S& cs = get_ref();
S& s = get_ref();
std::cout << cs.x;
std::cout << s.x;
}
};
Ответ
Храните S как поле ForInterview и возвращайте ссылку на это поле. Локальный S уничтожается при выходе из get_ref, поэтому возвращённая ссылка на него сразу становится висячей.
class ForInterview {
public:
struct S { int x = 1; };
const S& get_ref() const noexcept { return value; }
S& get_ref() noexcept { return value; }
private:
S value;
};
Теперь ссылка действительна, пока жив сам ForInterview. Обе перегрузки обращаются к одному объекту. Вызов get_ref у неконстантного экземпляра выбирает неконстантную перегрузку даже при последующем присваивании результата в const S&. Если независимое время жизни важнее ссылки, лучше возвращать значение.