У меня есть некоторые основные вопросы о C++. Рассмотрите следующий код, в котором я пытаюсь возвратить строку.
const std::string&
NumberHolder::getValueString() {
char valueCharArray[100];
sprintf_s(valueCharArray,"%f",_value);
std::string valueString(valueCharArray);
return valueString;
}
Я пытаюсь возвратить строку со значением участника класса, названного _value. Однако я получаю предупреждение, что я пытаюсь пасовать назад указатель на локальную переменную. Это - конечно, плохая вещь. Если я понимаю C++ достаточно в этой точке, это означает, что указатель, который я пасую назад, будет уже иметь, удаляют, обратился к нему к тому времени, когда кто-то пытается использовать его. Таким образом, я изменяю:
const std::string&
NumberHolder::getValueString() {
char valueCharArray[100];
sprintf_s(valueCharArray,"%f",_value);
std::string valueString = new std::string(valueCharArray);
return (*valueString);
}
Это должно создать указатель на стеке, который выживет за пределами этой функции. Две проблемы здесь, хотя: 1) это не компилирует так или иначе, и я не понимаю почему (ошибка = не может преобразовать из 'станд.:: представьте в виде строки *' к 'станд.:: basic_string <_Elem, _Traits, _Ax>') и 2) Это походит на потенциальную утечку памяти, потому что я в зависимости от кого-то еще для вызова, удаляют на этом парне. Какой шаблон я должен использовать здесь?
Вы побеждаете точку наличия std :: string
, выделяя ее в куче!
Просто верните его по значению следующим образом:
std::string NumberHolder::getValueString()
{
char valueCharArray[100];
sprintf_s(valueCharArray,"%f",_value);
return std::string(valueCharArray);
}
Практически каждый компилятор в настоящее время выполняет оптимизацию возвращаемого значения (RVO) в операторе return, поэтому копии не должны делаться. Примите во внимание следующее:
NumberHolder holder;
// ...
std::string returnedString = holder.getValueString();
С помощью RVO компилятор сгенерирует код для указанной выше реализации NumberHolder :: getValueString ()
, так что std :: string
создается в месте of ReturnString
, поэтому копии не требуются.
Вы получаете это предупреждение, потому что возвращаете ссылку на локальную строку, а не копию локальная строка. После возврата из функции локальная строка уничтожается, а возвращенная вами ссылка недействительна. Таким образом, вам нужно вернуть строку по значению, а не по ссылке:
std::string NumberHolder::getValueString()
Ваша первая попытка верна, если вы возвращаете временную переменную, но связываете ее в константной ссылке.
const std::string NumberHolder::getValueString(){}
const std::string& val = NumberHolder::getValueString();
const . Но ваша вторая попытка опасна, потому что нужно удалить кого-то еще.
std::string *valueString = new std::string(valueCharArray);
Вам потребуется создать переменную-указатель для хранения результата new
, поскольку она возвращает указатель. Однако идеальным решением было бы просто возврат по значению:
std::string NumberHolder::getValueString() {
...
return std::string(valueCharArray);
}