Вопрос

Есть ли в настоящее время веская причина использовать C-строки в C++?В моем учебнике они используются в некоторых моментах в примерах, и мне кажется, что было бы проще просто использовать std::string.

Это было полезно?

Решение

Единственная причина, по которой мне приходилось их использовать, - это взаимодействие со сторонними библиотеками, использующими строки стиля C.Могут также возникнуть экзотические ситуации, когда вы будете использовать строки в стиле C из соображений производительности, но чаще всего использование методов для строк C++, вероятно, происходит быстрее из-за встраивания, специализации и т. д.

Вы можете использовать c_str() во многих случаях при работе с такого рода API, но вы должны знать, что возвращаемый символ char * является константным, и вам не следует изменять строку с помощью этого указателя.В таких ситуациях вы все равно можете использовать вектор<char> и, по крайней мере, получить преимущество от более простого управления памятью.

Другие советы

Еще пара замечаний по управлению памятью:

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

Некоторые реализации std::string поддерживать функцию единого входа («оптимизация короткой строки» или «оптимизация небольшой строки»), где std::string класс содержит хранилище для строк до определенной длины.Это увеличивает размер std::string но часто значительно снижает частоту выделения/освобождения свободной памяти, повышая производительность.Если ваша реализация std::string не поддерживает единый вход, затем создается пустой std::string в стеке все равно будет выполняться распределение свободного хранилища.В этом случае использование временных строк C, выделенных в стеке, может оказаться полезным для критически важного к производительности кода, использующего строки.Конечно, при этом нужно быть осторожным, чтобы не выстрелить себе в ногу.

Потому что именно так они поступают из многочисленных API/библиотек?

Допустим, в вашем коде есть строковые константы, что является довольно распространенной необходимостью.Лучше определить их как строки C, чем как объекты C++ — более легкие, переносимые и т. д.Теперь, если вы собираетесь передавать эти строки различным функциям, было бы неплохо, если бы эти функции принимали строку C вместо того, чтобы требовать строковый объект C++.

Конечно, если строки изменяемы, гораздо удобнее использовать строковые объекты C++.

Контроль памяти.Недавно мне пришлось обрабатывать строки (фактически объекты из базы данных) размером около 200-300 МБ в многопоточном приложении.Это была ситуация, когда еще одна копия строки могла разорвать 32-битное адресное пространство.Мне нужно было точно знать, сколько существует копий строки.Хотя я пропагандист STL, я тогда использовал char *, потому что это давало мне гарантию того, что не будет выделено никакой дополнительной памяти или даже дополнительной копии.Я точно знал, сколько места для этого потребуется.

Кроме того, в стандартной обработке строк STL отсутствуют некоторые замечательные функции C для обработки/анализа строк.К счастью, std::string имеет метод c_str() для константного доступа к внутреннему буферу.Однако, чтобы использовать printf(), вам все равно придется использовать char * (какая сумасшедшая идея команды C++ не включать функциональность, подобную (s)printf, одну из самых полезных функций, когда-либо существовавших в C.Я надеюсь, что boost::format скоро будет включен в STL.

Если функция требует постоянный string Я по-прежнему предпочитаю использовать const char* (или const wchar_t*), даже если программа использует std::string, CString, EString или что-то еще.

В большой базе кода слишком много источников строк, чтобы быть уверенным, что вызывающая сторона получит строку в виде std::string, а 'const char*' является наименьшим общим знаменателем.

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

Если код C++ «глубокий» (близок к ядру, сильно зависит от библиотек C и т. д.), вы можете явно захотеть использовать строки C, чтобы избежать большого количества преобразований в std::string и из него.Конечно, если вы взаимодействуете с другими языковыми доменами (Python, Ruby и т. д.), вы можете сделать это по той же причине.В противном случае используйте std::string.

В некоторых сообщениях упоминаются проблемы с памятью.Это может быть хорошей причиной избегать std::string, но char*, вероятно, не лучшая замена.Это все еще объектно-ориентированный язык.Ваш собственный строковый класс, вероятно, лучше, чем char*.Это может быть даже более эффективно — например, вы можете применить оптимизацию малых строк.

В моем случае я пытался получить строки объемом около 1 ГБ из файла размером 2 ГБ, поместить их в записи примерно с 60 полями, а затем отсортировать их 7 раз по разным полям.Код моего предшественника с char* занимал 25 часов, мой код выполнялся за 1 час.

Потратив слишком много времени на отладку правил инициализации и всех мыслимых реализаций строк на нескольких платформах, мы требуем, чтобы статические строки были const char*.

Потратив слишком много времени на отладку плохого кода char* и утечек памяти, я предлагаю, чтобы все нестатические строки были строковыми объектами некоторого типа...пока профилирование не покажет, что можно и нужно сделать что-то лучше ;-)

При наличии выбора обычно нет причин выбирать примитивные строки C (char*) над строками C++ (std::string).Однако зачастую у вас нет такой роскоши, как выбор.Например, std::fstreamКонструкторы принимают строки C по историческим причинам.Кроме того, библиотеки C (как вы уже догадались!) используют строки C.

В вашем собственном коде C++ лучше всего использовать std::string и извлеките строку C объекта по мере необходимости, используя c_str() функция std::string.

Это зависит от библиотек, которые вы используете.Например, при работе с МФЦ, часто проще использовать CString при работе с различными частями Windows API.Также кажется, что он работает лучше, чем std::string в приложениях Win32.

Однако std::string является частью стандарта C++, поэтому, если вам нужна лучшая переносимость, используйте std::string.

Для таких приложений, как большинство встраиваемых платформ, где нет роскоши кучи для хранения обрабатываемых строк и где требуется детерминированное предварительное выделение строковых буферов.

Строки c не несут накладных расходов, связанных с классом.

Строки c обычно могут привести к более быстрому написанию кода, поскольку они ближе к машинному уровню.

Это не значит, что с их помощью нельзя писать плохой код.Их можно использовать неправильно, как и любую другую конструкцию.

Существует множество библиотечных запросов, которые требуют их по историческим причинам.

Научитесь использовать строки c и stl и используйте каждую из них, когда это имеет смысл.

1) «строковая константа» — это строка C (const char *), преобразование ее в const std::string& — это процесс времени выполнения, не обязательно простой или оптимизированный.2) библиотека fstream использует строки в стиле c для передачи имен файлов.

Мое практическое правило — передавать const std::string&, если я все равно собираюсь использовать данные как std::string (скажем, когда я сохраняю их в векторе), и const char * в других случаях.

Устаревший код, который не знает std::string.Кроме того, до C++11 открытие файлов с помощью std::ifstream или std::ofstream было возможно только с помощью const char* в качестве входных данных имени файла.

Строки STL, безусловно, гораздо проще использовать, и я не вижу причин не использовать их.

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

Обычно это делается потому, что вам нравится писать о переполнении буфера при обработке строк.Считаемые строки настолько превосходят завершаемые строки, что трудно понять, почему разработчики C вообще использовали завершаемые строки.Тогда это было плохое решение;сейчас это плохое решение.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top