web-dev-qa-db-ja.com

std :: stringはどのように実装されていますか?

Std :: stringの実装方法とc stringとの違いを知りたいのですが、標準が実装を指定していない場合、説明付きの実装は、標準で指定された文字列要件を満たす方法で素晴らしいでしょうか?

53
yesraaj

私が使用した事実上すべてのコンパイラーは、ランタイム用のソースコードを提供します。そのため、GCC、MSV、その他のいずれを使用していても、実装を見ることができます。ただし、std::stringの大部分またはすべてがテンプレートコードとして実装されるため、非常に読みにくくなります。

Scott Meyerの本、Effective STL には、std :: stringの実装に関する章があり、一般的なバリエーションのまともな概要です:「項目15:string実装のバリエーションに注意してください」。

彼は4つのバリエーションについて語っています。

  • ref-counted実装のいくつかのバリエーション(一般的にコピーオンライトとして知られています)-文字列オブジェクトが変更されずにコピーされると、refcountは増加しますが、実際の文字列データは増加しません。いずれかのオブジェクトが変更するまで、両方のオブジェクトは同じ参照カウントされたデータを指し、データの「書き込み時コピー」を引き起こします。バリエーションは、refcount、ロックなどが保存される場所にあります。

  • 「短い文字列の最適化」(SSO)実装。このバリアントでは、オブジェクトには通常のデータへのポインター、長さ、動的に割り当てられたバッファーのサイズなどが含まれます。ただし、文字列が十分に短い場合、バッファーを動的に割り当てる代わりにその領域を使用して文字列を保持します

また、 Herb Sutterの "More Exceptional C++" には付録(付録A:「マルチスレッド環境ではない最適化」)があります。同期の問題によるマルチスレッドアプリケーション。この記事はオンラインでも入手できます(ただし、本の内容とまったく同じかどうかはわかりません)。

これらの章は両方とも読む価値があります。

73
Michael Burr

std :: stringは、ある種の内部バッファーをラップし、そのバッファーを操作するためのメソッドを提供するクラスです。

Cの文字列は単なる文字の配列です

ここでstd :: stringがどのように機能するかのニュアンスをすべて説明するには、時間がかかりすぎます。 gccのソースコード http://gcc.gnu.org を見て、どのように実行されているかを確認してください。

12
Glen

このページの回答 に実装例があります。

さらに、gccがインストールされていると仮定して、gccの実装を確認できます。 そうでない場合は、SVNを介してソースコードにアクセスできます 。 std :: stringのほとんどは basic_string で実装されているため、そこから始めてください。

情報の別の可能なソースは Watcomのコンパイラ です

6
DVK

文字列のC++ソリューションは、Cバージョンとはまったく異なります。最初の最も重要な違いは、ASCIIZソリューションを使用するc、std :: stringおよびstd :: wstringが実際の文字列を格納するために2つのイテレータ(ポインタ)を使用していることです。文字列クラスの基本的な使用法は、動的に割り当てられたソリューションを提供するため、動的メモリ処理によるCPUオーバーヘッドのコストで、文字列処理がより快適になります。

おそらく既にご存知のように、Cには組み込みの汎用文字列型は含まれておらず、標準ライブラリを介した文字列操作のカップルのみを提供します。 CとC++の大きな違いの1つは、C++がラップされた機能を提供するため、偽のジェネリック型と見なすことができることです。

Cでは、文字列の長さを知りたい場合、文字列をウォークスルーする必要があります。std:: string :: size()メンバー関数は、基本的に1つの命令(end-begin)のみです。メモリがある限り、文字列を安全に追加できます。したがって、必要に応じて追加するとより大きなバッファが作成されるため、バッファオーバーフローのバグ(したがってエクスプロイト)を心配する必要はありません。

以前に誰かがここで言ったように、文字列はテンプレートの方法でベクトル機能から派生しているため、マルチバイト文字システムの処理が容易になります。 typedef std :: basic_string specific_str_t;を使用して、独自の文字列型を定義できます。テンプレートパラメータに任意のデータ型を含む式。

私は両方の側に十分な長所と短所があると思います:

C++文字列の長所:-特定のケースでの高速反復(サイズを確実に使用し、文字列の最後にいるかどうかを確認するためにメモリのデータを必要とせず、2つのポインタを比較します。キャッシング)-バッファ操作には文字列機能が詰め込まれているため、バッファの問題についての心配は少なくなります。

C++文字列の短所:-動的なメモリ割り当てのため、基本的な使用法はパフォーマンスに影響を与える可能性があります。 (残念ながら、元のバッファサイズを文字列オブジェクトに伝えることができるため、それを超えない限り、メモリから動的ブロックを割り当てません)-多くの場合、他の言語と比較して奇妙で一貫性のない名前です。これはstlに関しては悪いことですが、それを使用することができます。また、少し具体的なC++風の感じがします。 -テンプレートを頻繁に使用すると、標準ライブラリがヘッダーベースのソリューションを使用するようになるため、コンパイル時間に大きな影響があります。

4
progician

それは、使用する標準ライブラリに依存します。

STLPort は、たとえば文字列を実装するC++標準ライブラリの実装です。

3
Georg Schölly