std::string の実装方法と c 文字列との違いを知りたいです。標準で実装が指定されていない場合、説明付きの実装は、標準で指定された文字列要件をどのように満たすかという点で優れていますか?
5 に答える
私が使用したほぼすべてのコンパイラは、ランタイムのソースコードを提供します。したがって、GCCやMSVCなどを使用している場合でも、実装を確認することができます。ただし、大部分またはすべてがstd::string
テンプレートコードとして実装されるため、読み取りが非常に困難になる可能性があります。
ScottMeyerの著書であるEffectiveSTLには、std :: stringの実装に関する章があり、一般的なバリエーションの概要を説明しています。「項目15:string
実装のバリエーションに注意してください」。
彼は4つのバリエーションについて話します:
参照カウントの実装に関するいくつかのバリエーション(一般にコピーオンライトとして知られています)-文字列オブジェクトが変更されずにコピーされると、参照カウントは増加しますが、実際の文字列データは増加しません。両方のオブジェクトは、オブジェクトの1つがデータを変更するまで、同じrefcountedデータを指し、データの「コピーオンライト」を引き起こします。バリエーションは、refcount、locksなどが保存される場所にあります。
「ショートストリング最適化」(SSO)の実装。このバリアントでは、オブジェクトには、データへの通常のポインタ、長さ、動的に割り当てられたバッファのサイズなどが含まれます。ただし、文字列が十分に短い場合は、バッファを動的に割り当てる代わりに、その領域を使用して文字列を保持します。
また、 HerbSutterの「MoreExceptionalC ++」には、同期の問題が原因でコピーオンライトのrefcounted実装でパフォーマンスの問題が発生することが多い理由を説明する付録(付録A:「(マルチスレッドの世界では)ない最適化」)があります。その記事はオンラインでも入手できます(ただし、本の内容とまったく同じかどうかはわかりません)。
これらの章は両方とも読む価値があります。
std::string は、ある種の内部バッファーをラップし、そのバッファーを操作するためのメソッドを提供するクラスです。
C の文字列は単なる文字の配列です
ここで std::string がどのように機能するかのニュアンスをすべて説明すると、時間がかかりすぎます。gcc ソースコードhttp://gcc.gnu.orgを見て、彼らがどのようにそれを行っているかを正確に確認してください。
このページの回答に実装例があります。
さらに、gcc がインストールされていると仮定して、gcc の実装を確認できます。そうでない場合は、SVN 経由でソース コードにアクセスできます。std::string のほとんどはbasic_stringによって実装されているため、そこから始めてください。
別の情報源として考えられるのは、Watcom のコンパイラです。
文字列の C++ ソリューションは、C バージョンとはかなり異なります。最初の最も重要な違いは、c が ASCIIZ ソリューションを使用しているのに対して、std::string と std::wstring は実際の文字列を格納するために 2 つの反復子 (ポインター) を使用していることです。文字列クラスの基本的な使用法は、動的に割り当てられたソリューションを提供するため、動的メモリ処理による CPU オーバーヘッドのコストで、文字列処理がより快適になります。
おそらく既にご存じのとおり、C には組み込みの汎用文字列型は含まれておらず、標準ライブラリを介していくつかの文字列操作しか提供されていません。C と C++ の主な違いの 1 つは、C++ がラップされた機能を提供するため、偽のジェネリック型と見なすことができることです。
C では、文字列の長さを知りたい場合は文字列を調べる必要があります。 std::string::size() メンバー関数は、基本的に 1 つの命令 (終了 - 開始) のみです。メモリがある限り、文字列を安全に追加できます。そのため、バッファ オーバーフローのバグ (したがってエクスプロイト) について心配する必要はありません。追加により、必要に応じてより大きなバッファが作成されるためです。
誰かが以前にここで言ったように、文字列はテンプレート化された方法でベクトル機能から派生しているため、マルチバイト文字システムの処理が容易になります。typedef std::basic_string specific_str_t; を使用して、独自の文字列型を定義できます。テンプレート パラメーターに任意のデータ型を含む式。
双方に十分な長所と短所があると思います:
C++ 文字列の長所: - 特定のケースでは反復処理が速くなります (サイズを明確に使用し、2 つのポインターを比較して、文字列の末尾にいるかどうかを確認するためにメモリからのデータを必要としません。 caching) - バッファ操作には文字列機能がパックされているため、バッファの問題の心配が少なくなります。
C++ 文字列 短所: - 動的メモリ割り当てが原因で、基本的な使用法がパフォーマンスに影響を与える可能性があります。(幸い、元のバッファー サイズを文字列オブジェクトに伝えることができるため、それを超えない限り、メモリから動的ブロックを割り当てません) - 他の言語と比較して奇妙で一貫性のない名前がよくあります。これはあらゆる stl の悪い点ですが、慣れることができ、少し具体的な C++ っぽい感じになります。- テンプレートを頻繁に使用すると、標準ライブラリがヘッダー ベースのソリューションを使用することを余儀なくされるため、コンパイル時間に大きな影響を与えます。
それは、使用する標準ライブラリによって異なります。
たとえば、 STLPortは、とりわけ文字列を実装する C++ 標準ライブラリの実装です。