歴史的な理由から、C++ とその標準ライブラリは C 文字列 (文字配列) をサポートしており、多くの C++ コードは入力と出力に C 文字列を使用しています。
データを文字配列に保持する std::string の可能な実装を想像することもできます。これは通常、完全にプライベートな実装の詳細であり、クラスのパブリック インターフェイスを通じて公開されません。
編集: 明示的に言うと、クラスは通常、そのプライベート データの非 const ビューを公開しません。これが問題になる理由を理解するには、次のコードを想像してください。
std::string s("abc");
char* ps = s.c_str(); // ps[0] == 'a' and ps[3] == '\0'
ps[3] = 'd'; // string is not null terminated
printf("%s", s.c_str()); // printing non-terminated string.
このような変更により、クラスのユーザーは、不変条件、つまり次の不変条件を破る方法でプライベート データを変更できるようになります。
の契約の一部はoperator[]
、呼び出し元が文字列の長さ以上の引数を提供してはならないということです。at(size_t pos)
メンバー関数は、例外をスローして境界チェックを強制します。はstd::string::operator[]
引き続き安全に使用できませんが、 のようなポインター逆参照演算子とは異なり、少なくともcontractを文書化ps[3]
することは可能です。
編集の終わり
ただし、const char*
C 文字列を予期する関数との相互運用性をサポートするために、std::string
はこの文字バッファーを公開します。
もちろん、 と同様にstd::vector
、ユーザーは文字列内の個々の要素 (文字) を変更したい場合があります。これが、文字列が を提供する理由operator[]
です。
(実際には、string
実装には多くの場合、内部に保持する固定長の文字バッファーがあり、文字列の内容がその固定長を超えた場合にヒープに「再割り当て」されます。これは「小さな文字列の最適化」と呼ばれます)。
data()
完全にサービス可能なメンバー関数があるのに、なぜメンバー関数があるのc_str()
でしょうか? std::array
これはジェネリック プログラミングを単純化するためにあると思います。 メンバー関数std::vector
もあり、 s はコンテナーのように動作するように設計されています。data()
std::string