この記事によってできるだけ沢山の初心者プログラマーが救われますように。
私は今日、大雑把に言うとこんなコードを書きました。
const char * str1 = "test";
std::string str2 = "test";
if(str1 == str2.c_str() ) printf("Coincide!!");
ええ、私もそれを期待して書きました。
しかし、このコードでは期待通りの結果になりません。
ここで、if文内の右辺と左辺をひっくり返してみましょう。 するとなんと、今度は期待通りの結果になってくれるではありませんか!
…まあ、よく考えれば当たり前ですよね。(よく考えなくても当たり前ですが)
前者のコードはconst char型のポインタ同士を比較しているのに対して、後者のコードはstd::string::operator==の結果を受け取っているわけですね。
std::stringは文字列をコピーするクラスですから、当然その先頭アドレスは違ってくるはずです。
でも、文字列を比較するイメージだけど実は先頭アドレスを比較するだけというようなコードを今まで書いてきて、特に問題ありませんでしたよね?(私だけw?)
それはですね、 と書いたとき、testという文字列がメモリ上のどこかに記録されていて、その先頭アドレスをstr1とstr2が持つというネイティブコードにコンパイルされるから問題なく比較できるのだと考えられます。(あくまで私の推論です)
この論法で行くと、char[]型を使ったときやstrcpyを使った場合は文字列比較のときに==を使っても期待通りの結果が得られない可能性が高いですね。
ある文字列の途中の要素のインデックスを先頭アドレスとして持ちましたという場合ももちろんアウトですね。
私の場合は相当早い段階からstd::stringを使い始めたので今まで気づきませんでしたが、他の方々はどうなのでしょうか…?
ちなみに、今回わざわざconst char *型を使ったのは、正に ある文字列の途中の要素のインデックスを先頭アドレスとして持ちたかったからです。
抜き出した文字列を使っている間に元になった文字列が消滅することが無い状況の場合はこちらの方がパフォーマンスが良いですからね。
なにせstd::stringは文字列をコピーしてしまいますから。
それでは、良いプログラミングライフを。