|
CStringと三項演算子の問題
.netのCStringでは次のような記述ができます。
このように書くとNULLストリング("")の入ったCStringオブジェクトができます。まあ、わざわざこのように書かなくても、
と書けばNULLストリングで初期化されるので同じことですが。
ただ、VC6.0以前のCStringでは上の書き方をするとNULLからCStringに変換できないということでコンパイルエラーとなっていました。
.netで上のような書き方が通るようになったことで、微妙な問題がでてきます。
CString str;
LPCSTR ps = NULL;
ps = str.IsEmpty() ? NULL : str;
|
さて、上のプログラムではpsにNULLが入りそうですよね?でも実は入らないんです。これを実行すると、psにはNULLストリングへのポインタが入ります。(要するに何らかのメモリアドレスが入ります。)
なぜかというと、「C言語編_三項演算子とデータ型の問題」で書いた通り、三項演算子は、データ型を合わせないと、片方からもう片方へ暗黙的にデータ変換するという性質があります。この場合では、NULL(int型)とstr(CString型)を並べているので、NULLがCString型に暗黙的に変換されているわけです。
もっと言うとCString(NULL)という一時オブジェクトが作られて、それが持っている文字列バッファがpsに渡されているということですね。
ちなみに、VC6.0以前ではCStringにNULLを代入することはできなかったので、上のようなプログラムはコンパイルエラーとなっていました。
意図したとおりにstrが空だったらpsにNULLを入れたい場合は、次のように三項演算子が適用される前に、データ型を合わせれば大丈夫です。
ps = str.IsEmpty() ? LPCTSTR(NULL) : LPCTSTR(str1);
|
|