C ++: Можете ли вы вернуть значение локальной переменной из статического метода? - PullRequest
1 голос
/ 06 декабря 2010

Если у меня есть что-то вроде этого:

static const wchar_t* concatenate(const wchar_t* ws1, const wchar_t* ws2) {
    std::wstring s(ws1);
    s += std::wstring(ws2);
    return s.c_str();
}

Это не сработает, потому что область 's' находится внутри статического блока, поэтому содержимое стека будет выталкиваться, а адрес памяти для 's' больше не действителен, поэтому мой вопрос: как я могу это сделать?

Спасибо

Ответы [ 5 ]

12 голосов
/ 06 декабря 2010

Измените функцию, чтобы она возвращала std::wstring вместо wchar_t* и возвращала s.

static std::wstring concatenate(const wchar_t* ws1, const wchar_t* ws2) {
    std::wstring s(ws1);
    s += std::wstring(ws2);
    return s;
}

Кстати, это было бы одинаково верно для нестатических методов.

5 голосов
/ 06 декабря 2010

Тот факт, что функция static здесь не имеет значения. Вы могли бы вернуть s.c_str(), если бы переменная s была static, однако это было бы очень странно, поскольку s инициализировался бы только при первом вызове функции.

Моя рекомендация: просто верните std::wstring по значению.

std::wstring concatenate(const wchar_t* ws1, const wchar_t* ws2) {
    std::wstring s(ws1);
    s += std::wstring(ws2);
    return s;
}
2 голосов
/ 06 декабря 2010

Замените ваше заявление о возврате следующим:

wchar_t *ret = new wchar_t[s.length()+1];
wcscpy(ret, s.c_str());
return ret;

Функция, которую вы написали, не работает, потому что по возвращении вызывается деструктор для локальной переменной s, что освобождает память, на которую указывает s.c_str ().

1 голос
/ 06 декабря 2010

Тот факт, что функция-член (мы не говорим «метод» в C ++) static, не имеет значения.Вы можете вернуть локальную переменную по значению.То, что вы не можете сделать, это вернуть указатель или ссылку на локальную переменную или временное значение.s.c_str() создает указатель либо на временные данные, либо на часть локальных wstring.Поэтому мы не можем вернуть это.Возврат s (и корректировка типа возвращаемого значения для соответствия) - это нормально, потому что теперь мы возвращаемся по значению, которое (концептуально; оно может быть оптимизировано) делает копию локальной строки в стеке в слоте возвращаемого значения».

0 голосов
/ 06 декабря 2010

Если вы хотите сохранить подпись функции, попробуйте что-то вроде:

static const wchar_t* concatenate(const wchar_t* ws1, const wchar_t* ws2) {

    std::wstring s(ws1);
    wchar_t *r;

    s += std::wstring(ws2);

    /*
    * allocate the return value in heap (with room for the null termination)
    */
    r = new wchar_t[s.length() + 1]; 

    /*** copy ***/
    s.copy(r,s.length()+1);

    return r;
}

кстати (как сказали другие) вы можете вернуть весь объект s,

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...