C ++ строки, когда использовать что? - PullRequest
6 голосов
/ 10 ноября 2010

Прошло уже достаточно времени, когда я кодировал на C ++, и я думаю, что большинство, кто на самом деле кодирует на C ++, согласятся с тем, что одним из самых хитрых решений является выбор из почти головокружительного числа доступных типов строк. Я в основном предпочитаю ATL Cstring за его простоту использования и функциональность, но хотел бы сравнить имеющиеся варианты. Я проверил SO и не нашел никакого контента, который помог бы выбрать правильную строку. Существуют веб-сайты, которые сообщают о преобразованиях из одной строки в другую, но это не то, что нам нужно.

Хотелось бы иметь сравнение на основе специализации, производительности, переносимости (Windows, Mac, Linux / Unix и т. Д.), Простоты использования / функций, многоязычной поддержки (Unicode / MBCS), минусов (если есть) и любые другие особые случаи.

Я перечисляю строки, с которыми я столкнулся до сих пор. Я считаю, что их будет больше, поэтому мы можем отредактировать это позже, чтобы учесть другие варианты. Имейте в виду, я работал в основном на Windows, поэтому список отражает то же самое:

  1. char*
  2. std::string
  3. STL's basic_string
  4. ATL CString
  5. МФЦ CString
  6. BSTR
  7. _bstr_t
  8. CComBstr

Ответы [ 5 ]

7 голосов
/ 10 ноября 2010

Не хочу ограничивать ваш энтузиазм по этому поводу, но реально неэффективно смешивать множество строковых типов в одном проекте, поэтому, чем больше проект, тем больше неизбежно он должен опираться на std :: string(который является typedef для создания экземпляра basic_string в STL для типа char, а не для другой сущности), учитывая, что это единственная стандартная опция семантического значения.char * подходит в основном для строк фиксированного размера (например, строковых литералов, буферов фиксированного размера) или для взаимодействия с C.

Почему я говорю, что это неэффективно?Вы получите ненужные экземпляры шаблонов для множества строковых аргументов (перестановки даже для нескольких аргументов).Вы обнаруживаете, что вызываете функции, которые хотят загрузить результат в строку &, а затем должны вызвать .c_str () для этого и создать какой-то другой тип, делая избыточное выделение памяти.Даже const std :: string & требует строку временную, если она вызывается с использованием ASCIIZ char * (например, для буфера некоторого другого строкового типа).Когда вы хотите написать функцию для обработки типа строки, которую хочет использовать конкретный вызывающий объект, вас подталкивают к шаблонам и, следовательно, встроенному коду, более длительному времени компиляции и зависимостям перекомпиляции (есть некоторые способы смягчить это, но они становятся сложнымии чтобы быть удобными или автоматизированными, они, как правило, требуют изменений в различных типах строк - например, оператор приведения или функция-член, возвращающая некоторый общий интерфейс / прокси-объект).

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

2 голосов
/ 10 ноября 2010
  • char* - быстро, функции включают те, которые находятся в заголовке , подвержены ошибкам (слишком низкий уровень)

  • std::string - это на самом деле typedef для std::basic_string<char, char_traits<char> > Прекрасная вещь - во-первых, она тоже быстрая. Во-вторых, вы можете использовать все <алгоритмы>, потому что basic_string предоставляет итераторы. Для поддержки широких символов есть другой typedef, wstring, который std::basic_string<wchar_t, char_traits<wchar_t> >. Это (basic_string) является стандартным типом, поэтому является абсолютно переносимым. Я бы пошел с этим.

  • Строки CSL в ATL и MFC даже не предоставляют итераторов, поэтому для меня они отвратительны, потому что они являются оберткой для класса вокруг c-строк и очень плохо спроектированы. ИМХО

  • не знаю об остальном.

Надеюсь, что эта частичная информация поможет

2 голосов
/ 10 ноября 2010

Извините, история об обработке строк в C ++ слишком уныла для меня, чтобы написать эссе, но только пара моментов:

  • ATL и MFC CString - это одно и то же (одно и то жекод и все).Они были объединены несколько лет назад.

  • Если вы используете _bstr_t или CComBstr, вы, вероятно, не будете использовать BSTR, за исключением вызовов в API других людей, которые принимают BSTR.

1 голос
/ 10 ноября 2010

2 и 3 одинаковы. 4 и 5 тоже одинаковые. 7 и 8 являются обертками из 6. Таким образом, возможно, список содержит только строки C, стандартные строки C ++, строки Microsoft C ++ и строки Microsoft. Это дает вам ответ: в стандартном C ++ используйте стандартные строки C ++ (std::string)

1 голос
/ 10 ноября 2010

Очевидно, что только первые три являются переносимыми, поэтому они должны быть предпочтительными в большинстве случаев.Если вы используете C ++, вам следует избегать char * в большинстве случаев, так как необработанные указатели и массивы подвержены ошибкам.Исключением является взаимодействие с низкоуровневым C, таким как системные вызовы или драйверы.std:string должно быть предпочтительным по умолчанию, ИМХО, потому что оно прекрасно сочетается с остальными STL.

Опять же, ИМХО, если вам нужно работать, например, с MFC, вы должны работать со всем как std::string в вашей бизнес-логике и переводите в CString и обратно, когда вы нажимаете на функции WinApi.

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