4

クロスプラットフォームでの Unicode 文字列の使用に関する無数のディスカッション スレッドがありますが、私が取り組んでいる特定のプロジェクトで私を悩ませてきたいくつかの特定の懸念に対処することなく、幅広い意見があるようです。

私は、ほぼ 20 年前にさかのぼる大規模なクロスプラットフォーム C++ コード ベースを持っています。以下を含む、あらゆる種類の文字列実装の寄せ集めが含まれています。

  • char*
  • Pascal スタイルの文字列
  • std::string
  • 機能が重複する複数のカスタム クロスプラットフォーム クラス
  • CFString
  • あらゆる種類の定数文字列

このコード ベースは、モデルが完全に移植可能 (Mac OS / IOS / Android / Windows 7 & 8 / Unix) になることを期待して、完全に Unicode 文字列を使用し、強力な MVC アーキテクチャを実装するように書き直されているところです。

永続データが XML/UTF-8 として書き込まれている間、実行時オブジェクトでの文字列の使用に関していくつかのジレンマがあります。

  1. ストレージ、割り当て、および一般的な文字列操作の実装をきれいに隠すクラスを作成したいと考えています。C++ 演算子と代入のオーバーロードの奇跡を通して、関数が受け入れることができるすべての異なる文字列パラメーターをクラス インスタンスに置き換えることができるようになることを願っています。これにより、コード ベースの増分変換が可能になります。

  2. 私たちは常に文字列をスキャン/解析/分析していますが、永続オブジェクトに厳密に UTF-8 の基本実装を使用すると、パフォーマンスの問題が発生する可能性があるのではないかと心配しています。そうでない場合、Microsoft の VC++ と GNU の G++ にある最新の std::string は、単純な基本実装になるのでしょうか?

  3. Mac OS / IOS バージョンでは、最終的に文字列を CFString に「変換」する必要があります。CF 機能は豊富で、高度に最適化されています。CFStringCreateWithCharactersNoCopyCF にバッファ (たとえば、または)を提供して、独自のクラスで CFString を作成するのは良い戦略だと思いますCFStringCreateMutableWithExternalCharactersNoCopy。これにより、モデルからデータを取得した後に CFString が通常必要とする変換/割り当ての量を減らすことができるように思えます — おそらく適切な MVC 実装では、コントローラー/ビューはモデルが所有する実際の文字列にアクセスするべきではありませんか?

  4. C++ 11 は、これらのクロスプラットフォーム文字列の問題の状況を変えますか?

これらの問題はずっと前に解決されているはずだと私は推測していましたが、このサイト (および他のサイト) の回答を確認しても、解決したとは思えません。

4

1 に答える 1

4

ストレージ、割り当て、および一般的な文字列操作の実装をきれいに隠すクラスを作成したいと思います。C ++演算子と代入のオーバーロードの奇跡を通して、関数が受け入れることができるすべての異なる文字列パラメーターを置き換えるためにクラスインスタンスを置き換えることができることを望んでいます。これにより、コードベースの増分変換が可能になります。

std::stringにキャスト演算子を追加したように聞こえるconst char*ので、を呼び出す必要はありませんc_str()charつまり、UTF-16などではなく、UTF-8をストレージに使用する必要があります。

私たちは常に文字列をスキャン/解析/分析していますが、永続オブジェクトに厳密にUTF-8の基盤となる実装を使用すると、パフォーマンスの問題が発生する可能性があるのではないかと心配しています。そうでない場合std::string、MicrosoftのVC++およびGNUのG++に見られる最新の実装は、単純な基盤となる実装でしょうか?

これは他のいくつかの要因に依存します。一方では、入力にASCII以外のデータが多数含まれていて、一度に1つのコードポイントで分析する必要がある場合、UTF-8は非効率的である可能性があります。その場合、複数の文字列要素からコードポイントを再構築するための大文字と小文字の区別があまりないため、UTF-16またはUTF-32でさえより合理的である可能性があります。一方、パフォーマンスは、特に関数を呼び出すときに、参照によって文字列を渡すことができるか、コピーを作成する必要があるかどうかに大きく依存します。したがって、コピーが多すぎるのを避けるために、既存のコードベースにいくつかの変更が必要になる場合があります。

Mac OS / IOSバージョンでは、最終的に文字列をCFStringに「変換」する必要があります。CF機能は豊富で、高度に最適化されています。CFにバッファ(たとえば、CFStringCreateWithCharactersNoCopyまたはCFStringCreateMutableWithExternalCharactersNoCopy)を提供して、自分のクラスにCFStringsを作成させるのは良い戦略だと思います。これにより、モデルからデータをフェッチした後にCFStringが通常必要とする変換/割り当ての量を減らすことができるようです—おそらく適切なMVC実装では、コントローラー/ビューがモデルが所有する実際の文字列にアクセスできないようにする必要がありますか?

データバッファをコピーせずに文字列を作成する場合は、文字列にアクセスしている間、バッファが存続することを確認する必要があります。これは場合によっては当てはまるかもしれませんが、すべてではありません。char*一般に、問題は、に裏打ちされた問題と非常によく似ています。これが、自動キャストだけでなく、明示的な関数呼び出しであるstd::string理由です。c_str()このような変換を行うことにより、元のオブジェクトが割り当てられたままであることを保証する必要があります。一般的に、ビューに渡すconst std::string&ので、モデルが所有する文字列を誤って変更することはありません。文字列を保持または変更する必要がある場合は、文字列をコピーする必要があります。

C ++ 11は、これらのクロスプラットフォーム文字列の問題のいずれかの状況を変えますか?

C ++ 11は、多くの新しいスマートポインターの実装を提供します。これにより、文字列オブジェクトが割り当てられたままになる期間をより細かく制御できます。したがって、たとえばshared_prt<string>、クラスのデータストレージとしてを使用して、文字列の自動参照カウントと割り当て解除を取得できます。これにより、より高いレベルの抽象化が可能になりますが、現在のコードベースの機能からさらに離れている可能性があるため、移植が容易になるかどうかはわかりません。

于 2013-01-07T06:07:43.237 に答える