2016-06-27 4 views
0

У меня есть класс в моей программе, который имеет переменную-член, int-номер и функцию-член getName(), которая MEANT возвращает слова «Dice: #» как const char *, но с заменой # на число, хранящееся в классе.Не удается успешно вернуть const char * Я создал, вызвав c_str() в строке. (C++)

const char* getName(){ 
return "Dice:"; 
} 

работает отлично.

const char* getName(){ 
std::stringstream ss; 
ss << number; 
std::string s; 
s = "Dice: " + ss.str(); 
return s.c_str(); 
} 

НЕ работает нормально и возвращает то, что кажется мусором. Я не могу понять, как правильно это сделать. Если я использую cout для печати s.c_str(), он печатает то, что я ожидаю.

+0

Позаботьтесь о жизни: Строковый литерал является неизменным статическим хранилищем, автоматическая переменная - время действия. – Deduplicator

+0

Это странно. Можете ли вы опубликовать вывод мусора getName()? Это работает хорошо для меня. EDIT: Это неопределенное поведение, поскольку область const char * не распространяется за локальную переменную, а строки хранятся в статической постоянной памяти. –

+0

@TylerLewis: Это неопределенное поведение. –

ответ

5

Короткий и сладкий ответ заключается в том, что вы не можете этого сделать, как вы это задали.

Объект std::string, из которого вы получаете свой c_str(), находится в локальной области функции. Когда функция возвращает, что объект std::string уничтожается.

Это

std::string s; 

является локальным объектом функции. Когда функция возвращается, она перестает существовать. Он присоединяется к хору невидимым. Это уже не так. Это бывший объект.

И когда объект std::string уничтожается, любой его номер c_str() s более не действителен. Вот почему вы получаете мусор: неопределенное поведение.

Невозможно сделать это, не изменив его общий дизайн. Есть много способов продвижения вперед. Некоторые из возможностей:

Возвращает std::string в первую очередь

Просто вернуть std::string из getName(). Тот, кто называет это, может сохранить это std::string, на некоторое время, и захватить его c_str(), если он в этом нуждается.

Используйте std::string с другой областью

Если getName() является методом класса, вы могли бы иметь частный член класса std::string, есть getName() магазин строка там, и вернуть его c_str().

Поскольку оригинал std::string продолжает существовать, возвращается c_str(). Обратите внимание, что здесь есть некоторые подводные камни. Если вызывающий абонент снова вызовет getName(), ранее возвращенный c_str() больше не будет действителен.

Заключение

Просто получить в привычку использовать и работать с std::string с в коде C++. Для этого они нужны.

Имя «c_str()» должно быть ключом. Он дает вам строку, которая будет использоваться с кодом C, если в ближайшем окружении есть код С. Это строка C. Вы пишете здесь код С? Нет, вы пишете код на C++.

Если вы не пишете код C или не разговариваете с библиотекой C, вам не нужно использовать c_str(). Если вы пишете код на C++, вы должны использовать std::string s. Если вам нужно вызвать функцию библиотеки C, вызовите c_str(), чтобы передать соответствующий параметр функции библиотеки C, и больше не говорите об этой строке C.

+0

Спасибо! Я очень ценю тщательность этого ответа. Я собираюсь пройти и изменить свой код, чтобы в первую очередь вернуть строку и преобразовать в c_str() только там, где это необходимо. – CaptainTid

3

Вы создаете локальную переменную 's', а затем возвращаете указатель на strig с строковой памятью.

Когда функция возвращает строку выходит из области видимости (и так же указатель)

Лучшие ставки прочертовский изменить GetName вернуть зЬй :: строку, а затем, если вам нужно использовать c_str, использование где он возвращается.

std::string name = object.getName(); 
printf("name = %s", name.c_str()); 
+0

Я пытался избежать этого, так как это один из нескольких унаследованных классов, все из которых разделяют эту виртуальную функцию getName(), поэтому мне пришлось бы пропустить свой код и изменить их все, чтобы вернуть строку вместо этого, но если это единственный путь, то я думаю, вот что я сделаю! Спасибо за ваше время :) – CaptainTid

+0

Yup ... в основном, * «это не' const' ... »* –

 Смежные вопросы

  • Нет связанных вопросов^_^