Корректен ли этот код?

Я точно знаю что этот код некоректен, ибо возвращает ссылку на временный объект
// Возвращает ссылку на несуществующее значение
const std::string &getLink() {
    // Объект будет уничтожен при выходе из функции
    std::string tmpObject;
   // Возвращаем ссылку на него
   return tmpObject;
}

Но не могу сказать тоже самое по поводу Этого кода:
// Вроде бы тоже самое что и в предыдущем примере
const std::string &link = std::string("test");
// Но у меня есть сомнения

Кто может объяснить мне принципиальную разницу между этими двумя примерами?
  • Вопрос задан
  • 171 просмотр
Решения вопроса 1
fshp
@fshp
В первом случае у вас объект уничтожается раньше ссылки.

Во втором случае время жизни ссылки и объекта одинаково, так что это рабочий пример.

Нет никаких временных объектов. Есть стек и есть куча. Понимание разницы эти двух областей памяти отвечает на 90% вопросов в C++.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@Ariox41
В стандарте есть правило, по которому при создании константной ссылки на автоматически управляемый объект его время жизни расширяется до времени жизни константной ссылки. Однако это не относится к оператору return и есть особое правило для списков инициализации (подробнее тут). Соответственно, в следующем примере функция getRef некорректна, но функция foo реализована корректно.
const std::string &getRef() {
    std::string tmpObject = "123";
    return tmpObject;
}

void foo(){
    const std::string& ref = getRef();
    std::cout << ref; // Выведет 123
}


В любом случае, использование такого подхода не имеет смысла - можно просто полагаться на оптимизацию возвращаемого значения и писать так:

std::string getStr() {
    std::string tmpObject = "123";
    return tmpObject;
}

void foo(){
    std::string str = getStr();
    std::cout << str; // Выведет 123
}

// На крайний случай можно так - это точно корректно, но лучше не нужно - иначе кто-нибудь 
// может случайно удалить const, что приведёт к проблемам. 
void bar(){
    const std::string& ref = getStr();
    std::cout << ref; // Выведет 123
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через TM ID
Похожие вопросы