@varnak52

Почему из функции возвращается временный объект?

Добрый день!
Прохожу курс по С++ на Stepic
Задание звучит следующим образом:
Вам дан класс Foo:

struct Foo {
void say() const { std::cout << "Foo says: " << msg << "\n"; }
protected:
Foo(const char *msg) : msg(msg) { }
private:
const char *msg;
};
Как видно, создатель класса не хотел чтобы его использовали и "спрятал" конструктор класса. Но вам очень нужен объект этого класса, чтобы передать его в функцию foo_says:

void foo_says(const Foo& foo) { foo.say(); }
В этом задании вам нужно реализовать функцию get_foo (сигнатура которой намерено не приводится в задании полностью, вам нужно подумать и вывести ее самостоятельно) так, чтобы следующий код компилировался и работал:

foo_says(get_foo(msg));
Где msg — произвольная C-style строка.

Требования к реализации: при выполнении задания вам разрешено вводить любые вспомогательные функции и классы. Запрещено изменять определение класса Foo или функции foo_says. Вводить или выводить что-либо не нужно. Реализовывать функцию main не нужно


Задание решил :
struct Foo_2 : Foo
{
    Foo_2(const char *msg) : Foo(msg) {}
};
Foo get_foo(const char *msg)
{
    Foo_2 temp(msg);
    Foo * r = &temp;
    return *r;
}

Но совершенно не понимаю почему так происходит.
Подскажите пожалуйста почему можно использовать временное значение по выходу из функции? И правильно ли так делать, если нет то как нужно?
  • Вопрос задан
  • 330 просмотров
Решения вопроса 1
vt4a2h
@vt4a2h Куратор тега C++
Senior software engineer (C++/Qt/boost)
Там будет не временный объект, а тот же самый объект, что вы создали внутри функции. Даже копирования не будет. Хотя, у вас тут объект срезаться может поэтому ещё вопрос. Почитайте про RVO/NRVO.
Я немного поправил ваше решение:
Foo get_foo(const char *msg)
{
    return Foo_2(msg);
}

Так будет лучше.

Но! Тут важно понимать, что делать так в реальном коде нельзя, т.к. объект класса Foo_2, при некоторых условиях, срежется до объекта класса Foo. В вашем случае -- это не проблема. Но можно переписать как-то так, например:
const Foo &get_foo(const char *msg)
{
    static Foo_2 foo2(msg);
    return foo2;
}

Этот код тоже не для всех случаев подходит, т.к. get_foo будет возвращать всегда один и тот же объект с одним и тем же сообщением.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
BacCM
@BacCM
C++ почти с рождения
У тебя тут не внутренняя переменная возвращается, а копия объекта.
*r создается новый объект который инициализируется конструктором копирования из локального, тоже самое было бы если бы вернул temp

Ошибка была бы при функции вида
Foo& get_foo(const char *msg)
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы