Другой момент изучения C++: возврат строк от функций

У меня есть некоторые основные вопросы о 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) Это походит на потенциальную утечку памяти, потому что я в зависимости от кого-то еще для вызова, удаляют на этом парне. Какой шаблон я должен использовать здесь?

14
задан JnBrymn 19 July 2010 в 15:43
поделиться

4 ответа

Вы побеждаете точку наличия 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 , поэтому копии не требуются.

26
ответ дан 1 December 2019 в 06:35
поделиться

Вы получаете это предупреждение, потому что возвращаете ссылку на локальную строку, а не копию локальная строка. После возврата из функции локальная строка уничтожается, а возвращенная вами ссылка недействительна. Таким образом, вам нужно вернуть строку по значению, а не по ссылке:

std::string NumberHolder::getValueString()
16
ответ дан 1 December 2019 в 06:35
поделиться

Ваша первая попытка верна, если вы возвращаете временную переменную, но связываете ее в константной ссылке.

const std::string NumberHolder::getValueString(){}

const std::string& val = NumberHolder::getValueString();

const . Но ваша вторая попытка опасна, потому что нужно удалить кого-то еще.

3
ответ дан 1 December 2019 в 06:35
поделиться
std::string *valueString = new std::string(valueCharArray);

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

std::string NumberHolder::getValueString() {
    ...
    return std::string(valueCharArray);
}
0
ответ дан 1 December 2019 в 06:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: