Я вижу, что почти все современные API разработаны на языке C. Для этого есть причины: скорость обработки, язык низкого уровня, кроссплатформенность и так далее.
В настоящее время я программирую на C ++ из-за его объектной ориентации, использования строки, STL, но в основном потому, что это лучший язык C.
Однако, когда моим программам на C ++ необходимо взаимодействовать с C API, я действительно расстраиваюсь, когда мне нужно преобразовать типы char [] в строки C ++, затем обработать эти строки, используя его мощные методы, и, наконец, снова преобразовать из этих строк в char [] ( потому что API должен получить char []).
Если я повторю эти операции для миллионов записей, время обработки увеличится из-за задачи преобразования. По этой простой причине я считаю, что char [] в данный момент является препятствием для того, чтобы считать C ++ лучшим вариантом c.
Я хотел бы знать, чувствуете ли вы то же самое, если нет (я на это надеюсь!) Я действительно хотел бы знать, как лучше всего для C ++ сосуществовать с типами char [] без этих ужасных преобразований. Спасибо за внимание.
6 ответов
У строкового класса C ++ много проблем, и да, то, что вы описываете, является одной из них.
В частности, невозможно выполнить обработку строки без создания копии строки, что может быть дорогостоящим.
А поскольку практически все алгоритмы обработки строк реализованы как члены класса, их можно только использовать в классе строк.
Решение, с которым вы, возможно, захотите поэкспериментировать, - это комбинация Boost.Range и Boost.StringAlgo.
Диапазон позволяет создавать последовательности из пары итераторов. Они не владеют данными, поэтому не копируют строку. они просто указывают на начало и конец строки char *.
А Boost.StringAlgo реализует все стандартные строковые операции как функции, не являющиеся членами, которые могут применяться к любой последовательности символов. Как, например, диапазон Boost.
Комбинация этих двух библиотек в значительной степени решает проблему. Они позволяют избежать копирования строк для их обработки.
Другое решение - хранить строковые данные как std::string
все время . Когда вам нужно передать char*
некоторой функции API, просто передайте ей адрес первого символа. (& str [0]).
Проблема с этим вторым подходом заключается в том, что std :: string не гарантирует, что его строковый буфер завершается нулем, поэтому вам нужно либо полагаться на детали реализации, либо вручную добавить нулевой байт как часть строка.
Если вы используете std::vector<char>
вместо std::string
, базовым хранилищем будет массив C, к которому можно получить доступ с помощью &someVec[0]
. Однако вы теряете много std::string
удобств, таких как operator+
.
Тем не менее, я бы посоветовал просто избегать C API, которые максимально изменяют строки. Если вам нужно передать неизменяемую строку в функцию C, вы можете использовать c_str()
, который работает быстро и не копирует в большинстве реализаций std::string
.
Я не совсем понимаю, что вы имеете в виду под «конверсией», но разве следующего недостаточно для перехода между char*
, char[]
и std::string
?
char[] charString = {'a', 'b', 'c', '\0'};
std::string standardString(&charString[0]);
const char* stringPointer(standardString.c_str());
Я не уверен, почему вы были бы ограничены использованием строк C и по-прежнему имеете среду, в которой выполняется код C ++, но если вам действительно не нужны накладные расходы на преобразование, не выполняйте преобразование. Просто напишите процедуры, которые работают со строками C.
Другая причина для преобразования в строки стиля C ++ - связанная безопасность.
"... потому что это лучший C."
Ерунда. C ++ - намного худший диалект C. Проблемы, которые он решает, тривиальны, проблемы, которые он приносит, намного хуже, чем те, которые он решает.
Я не думаю, что это так плохо, как вы думаете.
Преобразование char [] в std :: string требует затрат, но если вы собираетесь изменять строку, вам все равно придется заплатить эту стоимость, будь то преобразование в std :: string или копирование в другой char [] буфер.
Обратное преобразование (через string.c_str ()) обычно тривиально. Обычно он возвращает указатель на внутренний буфер (просто не передавайте этот буфер коду, который его изменит).
Похожие вопросы
Новые вопросы
c++
C ++ - это язык программирования общего назначения. Первоначально он был разработан как расширение C и имеет аналогичный синтаксис, но теперь это совершенно другой язык. Используйте этот тег для вопросов о коде (который должен быть) скомпилирован с помощью компилятора C ++. Используйте тег для конкретной версии для вопросов, связанных с конкретной версией стандарта [C ++ 11], [C ++ 14], [C ++ 17], [C ++ 20] или [C ++ 23] и т. Д. .