Существует множество дискуссионных тем на тему кроссплатформенного использования Unicode-строки, но, похоже, существует широкий спектр мнений, без учета некоторых конкретных проблем, которые раздражали меня в конкретном проекте, над которым я работаю:
У меня большая кроссплатформенная кодовая база C ++, которая существует уже почти двадцать лет. Он содержит мешанину всевозможных реализаций строк, в том числе:
char*
std::string
CFString
Эта кодовая база находится в процессе переписывания, чтобы полностью использовать строки Unicode и реализовать сильную архитектуру MVC с надеждой, что модель будет полностью переносимой (Mac OS / IOS / Android / Windows 7 & 8 / Unix).
В то время как постоянные данные записываются в формате XML / UTF-8, существуют некоторые дилеммы, касающиеся использования строк в объектах времени выполнения:
Я хотел бы создать класс, который полностью скрывает реализацию операций хранения, выделения и общих строковых операций. Через чудо C ++ оператора и перегрузки присваивания я надеюсь, что смогу заменить экземпляр класса, чтобы заменить все различные строковые параметры, которые могут принимать функции. Это позволило бы для постепенного преобразования базы кода.
Мы постоянно сканируем / анализируем / анализируем строки, и я беспокоюсь, что использование строго UTF-8 базовой реализации для постоянных объектов может иметь проблемы с производительностью. Если нет, то будет ли современная std :: string, найденная в Microsoft VC ++ и GNU G ++, быть простой базовой реализацией?
В конечном счете, версии Mac OS / IOS должны быть преобразованы в CFString. Функции CF богаты и высоко оптимизированы. Я думаю, что было бы хорошей стратегией, чтобы мой собственный класс создавал CFStrings, предоставляя CF буфер (например, CFStringCreateWithCharactersNoCopy
или же CFStringCreateMutableWithExternalCharactersNoCopy
). Кажется, что это могло бы уменьшить количество преобразования / выделения, которое CFString обычно требовало бы после выборки данных из модели — хотя, возможно, в правильной реализации MVC у Controller / View не должно быть доступа к фактическим строкам, принадлежащим модели?
Изменяет ли C ++ 11 картинку для решения этих кроссплатформенных проблем со строками?
Я бы предположил, что эти проблемы должны были быть решены очень давно, но из рассмотрения ответов на этом сайте (и других) я не вижу, что это так.
Я хотел бы создать класс, который полностью скрывает реализацию операций хранения, выделения и общих строковых операций. Через чудо C ++ оператора и перегрузки присваивания я надеюсь, что смогу заменить экземпляр класса, чтобы заменить все различные строковые параметры, которые могут принимать функции. Это позволило бы для постепенного преобразования базы кода.
Звучит как std::string
с добавленным оператором приведения к const char*
так что вам не придется звонить c_str()
, Что будет означать, что вы должны использовать char
и UTF-8 для хранения, в отличие от UTF-16 или аналогичного.
Мы постоянно сканируем / анализируем / анализируем строки, и я беспокоюсь, что использование строго UTF-8 базовой реализации для постоянных объектов может иметь проблемы с производительностью. Если нет, то будет ли современный
std::string
Нашли в Microsoft VC ++ и GNU G ++ простую базовую реализацию?
Это зависит от нескольких других факторов. С одной стороны, UTF-8 может быть быть неэффективным, если ваши входные данные содержат много не ascii данных, и вы должны анализировать их по одной кодовой точке за раз. В этом случае UTF-16 или даже UTF-32 могут быть более разумными, так как у вас не будет столько различий в регистрах для повторной сборки кодовых точек из нескольких строковых элементов. С другой стороны, производительность в значительной степени зависит от того, можете ли вы передавать строки по ссылке или создавать копию, особенно при вызове функции. Поэтому могут потребоваться некоторые модификации существующей кодовой базы, чтобы избежать слишком большого количества копий.
В конечном счете, версии Mac OS / IOS должны быть преобразованы в CFString. Функции CF богаты и высоко оптимизированы. Я думаю, что было бы хорошей стратегией, чтобы мой собственный класс создавал CFStrings, предоставляя CF буфер (например, CFStringCreateWithCharactersNoCopy или CFStringCreateMutableWithExternalCharactersNoCopy). Кажется, что это могло бы уменьшить количество преобразования / выделения, которое CFString обычно требовало бы после выборки данных из модели — хотя, возможно, в правильной реализации MVC у Controller / View не должно быть доступа к фактическим строкам, принадлежащим модели?
Когда вы создаете строки без копирования буфера данных, вам нужно будет убедиться, что буфер живет до тех пор, пока к строке обращаются. Это может быть правдой в некоторых случаях, но не во всех. В целом проблемы очень похожи на те, с которыми вы сталкиваетесь. char*
при поддержке std::string
что является причиной, почему c_str()
явный вызов функции, а не только автоматическое приведение. Делая такое преобразование, вы должны гарантировать, что исходный объект остается выделенным. В общем, я бы сдал const std::string&
к представлениям, поэтому они не будут случайно менять строки, принадлежащие модели. Если им нужно сохранить или изменить строку, им придется скопировать ее.
Изменяет ли C ++ 11 картинку для решения этих кроссплатформенных проблем со строками?
C ++ 11 предоставляет ряд новых реализаций интеллектуальных указателей, которые позволяют вам лучше контролировать, как долго остается строковый объект. Так что вы могли бы, например, использовать shared_prt<string>
в качестве хранилища данных вашего класса, для получения автоматического подсчета ссылок и освобождения строк. Это даст вам более высокий уровень абстракции, но может оказаться еще дальше от того, что делает ваша текущая кодовая база, поэтому я не уверен, облегчит ли это вам перенос.
Других решений пока нет …