C ++ возвращает путаницу временных объектов

У меня довольно простой вопрос 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() вместо?

Код, подобный приведенному выше, кажется, работает, но я подозреваю, что это только потому, что память, содержащая «временный» объект, еще не была перезаписана чем-то другим, когда я его использую?

Должен признаться, я в целом довольно запутан в таких ситуациях, я был бы признателен, если бы кто-то мог объяснить мне все эти «временные объекты» (или просто указать мне правильное направление).

спасибо заранее

7

Решение

Вы возвращаете временный объект, но поскольку вы возвращаете его по значению, копия создается. Если вы вернете указатель или ссылку на временный объект, это будет ошибкой.

Если вы измените тип возврата на const char * и вернуться ss.str().c_str() вы бы вернули указатель на некоторый буфер временного std::string вернулся ss.str() и это было бы плохо.

12

Другие решения

Как вы видите Stringstream :: ул () возвращается std::string объект. Вы возвращаетесь std::string без ссылки это означает, что без оптимизации RVO (NRVO) конструктор копирования будет вызывать и создавать действительные std::string объект. С оптимизацией std::string будет перемещен без конструктора копирования. Но если вернется std::string& он потерпит крах, потому что этот объект будет уничтожен после возврата функции. Тот же эффект будет с const char * потому что после уничтожения этот указатель будет указывать на плохую память, и это опасная ситуация.

3

Предположим это: T val = some_function()когда вы возвращаете значение из some_function C ++ скопировать возвращаемое значение в val используя указанный конструктор копирования или встроенный оператор. Так что если вы вернете int или же std::string нет никаких проблем, но если вы вернете указатель на память, которая будет освобождена в конце функции, упс !! Ваш указатель будет указывать на недопустимую память. Например, рассмотрим это:

const char* some_function() {
std::string res( ... );
//...
return res.c_str();
}

Вы возвращаете указатель на данные, которые будут освобождены, как только функция вернется (так как res будет уничтожен, и он освободит свои внутренние данные), так что вы получите адрес, но этот адрес не указывает на то, что вы, возможно, ожидаете!

1
По вопросам рекламы [email protected]