85

C ++でsの配列を管理するために、いつ使用するstd::string必要があり、いつ使用する必要がありますか?char*char

char*パフォーマンス(速度)が重要であり、メモリ管理のためにリスクの高いビジネスの一部を受け入れる意思がある場合は、使用する必要があるようです。

考慮すべき他のシナリオはありますか?

4

12 に答える 12

58

私の見解は次のとおりです。

  • 「C」コードを呼び出さない場合は、char*を使用しないでください。
  • 常にstd::stringを使用してください:より簡単で、よりフレンドリーで、最適化されており、標準であり、バグが発生するのを防ぎ、チェックされ、動作することが証明されています。
于 2009-04-29T08:16:54.537 に答える
57

コピーを避けるためにsが大きい場合は参照によって、またはインスタンスへのポインターを渡すことができるstd::stringため、ポインターを使用した実際の利点はわかりませんchar

私はstd::string/wstringを多かれ少なかれ実際のテキストであるすべてに使用します。char *ただし、他のタイプのデータには便利であり、本来のように割り当てが解除されることを確認できます。そうstd::vector<char>でなければ行く方法です。

これらすべてにはおそらく例外があります。

于 2009-04-29T07:20:41.193 に答える
14

生の文字列の使用法

はい、時々あなたは本当にこれを行うことができます。const char *、スタックに割り当てられたchar配列、および文字列リテラルを使用する場合、メモリ割り当てがまったくないような方法でそれを行うことができます。

このようなコードを書くには、文字列やベクトルを使用するよりも多くの場合、より多くの思考と注意が必要ですが、適切な手法を使用すれば実行できます。適切な手法を使用すれば、コードは安全ですが、char []にコピーするときは、コピーする文字列の長さを保証するか、特大の文字列を適切にチェックして処理する必要があります。そうしないことが、strcpyファミリーの関数に安全ではないという評判を与えた理由です。

テンプレートが安全なcharバッファの作成にどのように役立つか

char []バッファの安全性については、バッファサイズを処理するためのカプセル化を作成できるため、テンプレートが役立ちます。このようなテンプレートは、strcpyの安全な代替品を提供するために、たとえばMicrosoftによって実装されています。ここでの例は私自身のコードから抽出されたものであり、実際のコードにはさらに多くのメソッドがありますが、これは基本的な考え方を伝えるのに十分なはずです。

template <int Size>
class BString
{
  char _data[Size];

  public:
  BString()
  {
    _data[0]=0;
    // note: last character will always stay zero
    // if not, overflow occurred
    // all constructors should contain last element initialization
    // so that it can be verified during destruction
    _data[Size-1]=0;
  }
  const BString &operator = (const char *src)
  {
    strncpy(_data,src,Size-1);
    return *this;
  }

  operator const char *() const {return _data;}
};

//! overloads that make conversion of C code easier 
template <int Size>
inline const BString<Size> & strcpy(BString<Size> &dst, const char *src)
{
  return dst = src;
}
于 2009-04-29T08:12:54.313 に答える
9

使用しなければならない場合とそうでない場合の1つchar*std::string、静的文字列定数が必要な場合です。その理由は、モジュールが静的変数を初期化する順序を制御できず、別のモジュールの別のグローバルオブジェクトが、初期化される前に文字列を参照する可能性があるためです。http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Static_and_Global_Variables

std::string長所:

  • あなたのためにメモリを管理します(文字列は大きくなる可能性があり、実装はより大きなバッファを割り当てます)
  • 高レベルのプログラミングインターフェイスは、STLの他の部分とうまく連携します。

std::string短所:-2つの異なるSTL文字列インスタンスは、同じ基になるバッファを共有できません。したがって、値を渡すと、常に新しいコピーが取得されます。-パフォーマンスの低下はありますが、特別な要件がない限り、無視できると思います。

于 2009-04-29T07:56:13.027 に答える
8

char*次の場合に使用することを検討する必要があります。

  • この配列はパラメータで渡されます。
  • 配列の最大サイズを事前に知っています(知っているか、強制します)。
  • この配列では変換を行いません。

実際、C ++では、char*オプション、ファイル名などとして、固定された小さな単語によく使用されます...

于 2009-04-29T07:17:29.687 に答える
5

c ++ std :: stringを使用する場合:

  • strings全体として、より安全ですchar*。通常、あなたが何かをしているときは、char*物事が正しいことを確認するために物事をチェックする必要がありstringます。クラスでは、これはすべてあなたのために行われます。
  • 通常、を使用する場合は、割り当てたメモリを解放する必要があります。破棄されると内部バッファが解放されるため、これchar*を行う必要はありません。string
  • string■C++でうまく機能しstringstream、フォーマットされたIOは非常に簡単です。

charを使用する場合*

  • を使用char*すると、舞台裏で何が起こっているかをより細かく制御できます。つまり、必要に応じてパフォーマンスを調整できます。
于 2009-04-29T07:54:05.327 に答える
4

ライブラリを作成する場合は、パラメータとして(const)char*を使用します。std :: stringの実装は、コンパイラによって異なります。

于 2009-04-29T14:59:38.780 に答える
3

Cライブラリを使用する場合は、C文字列を処理する必要があります。APIをCに公開する場合も同様です。

于 2009-04-29T07:54:33.110 に答える
2

std :: string(egなどfind)に対するほとんどの操作は可能な限り最適化されることが期待できるため、少なくとも純粋なCの対応物と同様に実行される可能性があります。

std :: stringイテレータは、基になるchar配列へのポインタにマップされることがよくあることにも注意してください。したがって、イテレータの上で考案するアルゴリズムは、パフォーマンスの点でchar*の上にある同じアルゴリズムと本質的に同じです。

注意すべき点は次のとおりです。たとえば、operator[]ほとんどのSTL実装は境界チェックを実行しないため、これを基になる文字配列に対する同じ操作に変換する必要があります。AFAIK STLPortはオプションで境界チェックを実行できます。その時点で、この演算子は少し遅くなります。

では、std :: stringを使用すると何が得られますか?手動のメモリ管理から解放されます。アレイのサイズ変更が簡単になり、通常、メモリの解放について考える必要が少なくなります。

文字列のサイズを変更するときにパフォーマンスが心配reserveな場合は、便利な関数があります。

于 2009-04-29T08:16:28.843 に答える
1

テキストなどで文字の配列を使用している場合は、std::stringをより柔軟で使いやすく使用してください。データストレージのような他の目的で使用する場合はどうなりますか?配列を使用する(ベクトルを優先する)

于 2009-04-29T07:11:27.300 に答える
1

パフォーマンスが重要な場合でも、より適切に使用vector<char>できます。事前にメモリを割り当てることができ(reserve()メソッド)、メモリリークを回避するのに役立ちます。vector :: operator []を使用するとオーバーヘッドが発生しますが、いつでもバッファのアドレスを抽出して、char*の場合とまったく同じようにインデックスを付けることができます。

于 2009-04-29T07:15:50.207 に答える
-1

AFAIKは、内部的にほとんどのstd :: stringにコピーオンライトを実装し、文字列が参照によって渡されない場合でも、オーバーヘッドを回避するためにカウントされたセマンティクスを参照します。

于 2009-04-29T08:07:30.410 に答える