2010-01-20 3 views

ответ

8

Для строковых литералов и только для строковых констант, которые исходят из литералов, я бы использовал const char[]. Основным преимуществом std::string является то, что он имеет управление памятью бесплатно, но это не проблема с строковыми литералами.

Это фактический тип литерала в любом случае, и его можно использовать непосредственно в любом API, который требует либо старых строк с нулевым завершающим строком, либо строк C++ (неявное преобразование). Вы также получаете реализацию размера времени компиляции, используя массив вместо указателя.

Теперь при определении функциональных интерфейсов, и даже если константы намерены пройти, я предпочел бы std::string, а не const char*, так как в последнем случае размер теряется и, возможно, потребуется пересчитать.

Из моего собственного опыта. Я устал от написания .c_str() на каждом вызове библиотеки протоколирования (использующей переменные аргументы) для литеральных строк с сообщениями об ошибках.

2

Вы должны использовать то, что больше подходит для вас. Если никаких особых требований я бы не использовал std::string, потому что он выполняет всю работу с памятью.

Для струнных литералов я бы использовал const char*. Причиной против const char[] является то, что вы можете использовать const char* для инициализации другой константы. Проверьте следующий код:

const char str1[] = "str1"; 
const char* str11 = "str11"; 

const char str2[] = str1; // <<< compile error 
const char* str22 = str11; // <<< OK 

строковых литералов имеет статическую продолжительность хранения (в соответствии с 2.13.4/2), поэтому указатель const char* будет действовать до завершения программы.

+0

И быстрее во многих реализациях STL благодаря копированию на механизм записи, если вы используете одни и те же строки во многих разных местах, что также упрощает их использование, чем простые строки C. Помимо этого, если вам нужно поддерживать многие языки, я предпочел бы использовать std :: wstring. – jdehaan

+0

@jdehaan: Я был бы удивлен, если бы были (m) любые реализации библиотеки std (а не STL-реализации, поскольку 'std :: string' не был частью STL), которые до сих пор делают COW. В средах МТ это обычно превращается в пессимизацию. Я думаю, что небольшая оптимизация строк (небольшие строки не выделены в куче, а в стеке) - это то, что обычно нравится сейчас. – sbi

+0

Копирование на запись удаляется (если все еще присутствует) в большинстве реализаций. У этого есть проблемы в многопоточных средах, поскольку некоторые операции, которые кажутся потокобезопасными с точки зрения пользователя (они относятся к различным std :: string), могут быть небезопасными потоками. Рассмотрим, что строка копируется с каждой копией, переданной на разные потоки для изменения. Каждый поток имеет свою собственную строку, не имеет общих объектов, но на самом деле во внутренней реализации «copy-on-write» может быть состояние гонки. Добавление механизма блокировки в библиотеку во многих случаях приводит его к более медленному, чем простая реализация. –

2

Что вы будете делать с этим? Что ожидают ваши методы?

const char легче в хранении, но не имеет силы std :: string или безопасности при его использовании. Однако, если у вас много API-интерфейсов C, это может быть более разумный выбор.

std :: string будет предпочтительным вариантом.

+2

.c_str() - ваш друг :) – JPvdMerwe

+0

@JPvdMerwe: theatrus правильный. Если все, что вы делаете, это передача константной строки в функции, требующие 'const char *', нет смысла использовать 'std :: string' /' .c_str() '. Массив 'const'' char' не имеет стоимости вызова конструктора и может быть передан непосредственно в функции, что делает его более дешевым, чтобы построить и дешевле перейти к функциям, чем 'std :: string'. –

+0

Да для струнных литералов, я полностью согласен, не теряя времени на процессорное время. – JPvdMerwe

1

Я предпочитаю const std::string над const char * для струнных литералов. Поскольку передача строковых литералов в функции, принимающие const std::string &, будет молча создавать строку каждый раз, когда они вызывается вместо одного. Однако, если я в основном использую литерал с функциями, ожидающими const char *, я буду использовать это вместо этого.

Я предпочитаю std::string для apis.

Конечно, если я использую unicode, я использую std::wstring и wchar_t.

+0

Я сделал то же предположение о unicode, но это интересно: http://utf8everywhere.org/. Оказывается, что wchar_t является чем-то вроде реликвии более простого времени в истории Unicode, так как Win32 API является родным WCHAR. Жизнь может быть лучше, если вы просто придерживаетесь UTF-8 и std :: string. – terriblememory