33

クラス インターフェイスを設計しているときに、かなり頻繁にconst char*orを使用する必要があるかどうかを座って考えます。const std::string&

次の 2 つの関数プロトタイプを使用します。

void foo(const char* str);
void foo(std::string str);

関数が文字列を格納する場合、foo文字列を渡し、可能な場合はムーブ セマンティクスを利用できるため、2 番目のオプションの方が適しています。ただし、foo文字列を読み取るだけでよい場合、const char*解決策はより良いでしょうか?

パフォーマンスの観点から、一時的std::stringなものを作成する必要はありません。ただし、既存の文字列を引数として関数を呼び出すと、邪魔に見えます: foo(mystr.c_str()). さらに悪いことに、将来のある時点でより高度な操作をアレイに対して実行する必要がある場合、またはコピーを保存する必要がある場合は、インターフェイスを変更する必要があります。

だから私の質問はこれです:

個人的なものであれ、そうでないものであれ、明確に定義された規則があり、それがいつ、std::stringまたはconst char*より良い選択であるかを規定していますか? さらに、新しいプロジェクトを開始するときは、使用方法に一貫性を持たせるのが最善ですか、それとも現在のコードのチャンクに最適な方を採用するのが最善でしょうか?

4

7 に答える 7

53

const char*は C への逆戻りです。まともな C++ では、それを使用するのはextern "C"API だけです。

std::stringには多くの利点があります。

  1. 一定時間size()機能を提供します。a の長さを発見するにconst char*は線形時間がかかります。

  2. 有効であることが保証されています。Aconst char*が null であることを確認する必要があり、無効なデータ (null ターミネータが欠落しているデータ) を渡す可能性は十分にあります。このような事態が発生すると、クラッシュまたはそれ以上の結果になることがほぼ保証されています。

  3. 標準アルゴリズムと互換性があります。

関数を呼び出すために を作成しなければならないことによるパフォーマンスへの影響が心配な場合はstd::string、標準ライブラリが使用するアプローチを取ることを検討してください。代わりに、関数を変更してイテレータのペアを使用します。const std::string&次に、イテレータ ペアへの委譲を行う便利なオーバーロードを提供できます。

于 2014-04-30T08:47:31.243 に答える
21

個人的な経験からのいくつかのメモ。(追加したタグに従って) C++ プロジェクトに取り組んでいる場合はstd::string、できるだけ提供されているものに固執してください。すべての構造の中で最も基本的な万能の文字列を再発明しようとしないでください。基本的な弦を再発明し、その後何ヶ月もかけて微調整したプロジェクトをいくつか見ました。

C++ プロジェクトの場合、変数を導入した時点からandchar*などの標準 C 関数にフォールバックします(2 つ挙げるとすれば ...)。そして、この時点から、手動でメモリ割り当てを管理するなどして、プロジェクトが混乱し始めます...strlen()strcpy

パラメータとして受け入れるサードパーティのライブラリと対話する必要がある場合const char*(そして、それらのライブラリを信頼していると思います-つまりconst_cast、貧弱な文字列で邪悪なことをするために constness を離れないことを信頼std::string::c_str()const char*ています)あなたの文字列の。

受け入れるメソッドを持つライブラリと対話する必要がある場合char*は、文字列のコピーを取得し、それをライブラリへの入力パラメーターとして使用することを強くお勧めしますc_str()(もちろん、余分なコピーを削除することを忘れないでください)。

これらの余分なポイントに加えて、Angew の応答からの 3 つのポイントすべてに同意します。

于 2014-04-30T08:57:06.007 に答える
6

std::stringc++ では、常に最初の選択肢にする必要があります。余分なコピーのオーバーヘッドを避けるために、ほとんどの場合、引数を参照としてconst渡し、可能な限りいつでも参照する必要があります。

その場合、関数の署名は次のようになります

void foo(std::string &str);

引数がconstの場合、このように

void foo(const std::string &str);

ここで見ることができるこの const キーワードの利点があります

于 2014-04-30T08:45:43.887 に答える
4

使用する代わりに

void foo(std::string str); 

あなたが使用できる

void foo(const std::string& str);

これはと同等です

void foo(const char* str);

使用に関しては、参照を渡すときにメモリが割り当てられないためです。しかし、C++ の文字列の場合、私は間違いなくstd::string. ランダム データまたは C 互換インターフェイスの場合は、そうしません。

于 2014-04-30T08:45:40.140 に答える
4

std::string は、生の char * を使用するよりも優れています。割り当て、割り当て解除、サイズ関連の問題を管理して、オーバーフロー、アンダーフロー、サイズの境界を超えないように注意する必要があります。std::string に対して、これらはすべて抽象化によって処理されます

于 2014-04-30T08:45:12.903 に答える