У меня довольно простой вопрос C ++, рассмотрим функцию, которая принимает некоторые входные параметры и создает std::string
что из этих параметров, как показано ниже:
std::string constructString( int some_parameter ) {
std::stringstream ss;
// Construct a string (arbitrarily complex)
ss << "Some parameter is " << some_parameter << " right now";
return ss.str(); //Am I not returning a temporary object here?
}
Я понимаю, что stringstream-объект выйдет из области видимости, когда функция вернется, но разве это не делает недействительной и созданную строку?
Что бы произошло, если бы я изменил тип возвращаемого значения на const char *
и вернулся ss.str().c_str()
вместо?
Код, подобный приведенному выше, кажется, работает, но я подозреваю, что это только потому, что память, содержащая «временный» объект, еще не была перезаписана чем-то другим, когда я его использую?
Должен признаться, я в целом довольно запутан в таких ситуациях, я был бы признателен, если бы кто-то мог объяснить мне все эти «временные объекты» (или просто указать мне правильное направление).
спасибо заранее
Вы возвращаете временный объект, но поскольку вы возвращаете его по значению, копия создается. Если вы вернете указатель или ссылку на временный объект, это будет ошибкой.
Если вы измените тип возврата на const char *
и вернуться ss.str().c_str()
вы бы вернули указатель на некоторый буфер временного std::string
вернулся ss.str()
и это было бы плохо.
Как вы видите Stringstream :: ул () возвращается std::string
объект. Вы возвращаетесь std::string
без ссылки это означает, что без оптимизации RVO (NRVO) конструктор копирования будет вызывать и создавать действительные std::string
объект. С оптимизацией std::string
будет перемещен без конструктора копирования. Но если вернется std::string&
он потерпит крах, потому что этот объект будет уничтожен после возврата функции. Тот же эффект будет с const char *
потому что после уничтожения этот указатель будет указывать на плохую память, и это опасная ситуация.
Предположим это: T val = some_function()
когда вы возвращаете значение из some_function
C ++ скопировать возвращаемое значение в val
используя указанный конструктор копирования или встроенный оператор. Так что если вы вернете int
или же std::string
нет никаких проблем, но если вы вернете указатель на память, которая будет освобождена в конце функции, упс !! Ваш указатель будет указывать на недопустимую память. Например, рассмотрим это:
const char* some_function() {
std::string res( ... );
//...
return res.c_str();
}
Вы возвращаете указатель на данные, которые будут освобождены, как только функция вернется (так как res
будет уничтожен, и он освободит свои внутренние данные), так что вы получите адрес, но этот адрес не указывает на то, что вы, возможно, ожидаете!