C++ で演算子キャストを使用すると、関数呼び出しが呼び出されていることが明らかでないため、コードの読者が混乱する可能性があります。そうは言っても、私はその使用が推奨されていないのを見てきました.
しかし、どのような状況で演算子キャストを使用することが適切であり、それがもたらす可能性のある混乱を超える価値があるのでしょうか?
C++ で演算子キャストを使用すると、関数呼び出しが呼び出されていることが明らかでないため、コードの読者が混乱する可能性があります。そうは言っても、私はその使用が推奨されていないのを見てきました.
しかし、どのような状況で演算子キャストを使用することが適切であり、それがもたらす可能性のある混乱を超える価値があるのでしょうか?
演算子のキャストは、ラッパー オブジェクトの C++ イディオムで非常に役立ちます。たとえば、文字列クラスのコピー オン ライト実装があるとします。次のように、ユーザーが自然にインデックスを作成できるようにしたい
const String s = "abc";
assert(s[0] == 'a');
// given
char String::operator[](int) const
これまでのところ、これでうまくいくと思われるでしょう。しかし、誰かがあなたの文字列を変更したい場合はどうなりますか? おそらく、これは機能しますか?
String s = "abc";
s[0] = 'z';
assert(s[0] == 'z');
// given
char & String::operator[](int)
しかし、この実装は非定数文字への参照を提供します。したがって、誰かがいつでもその参照を使用して文字列を変更できます。そのため、参照を渡す前に、内部で文字列のコピーを実行して、他の文字列が変更されないようにする必要があります。したがってoperator[]
、コピーを強制せずに非 const 文字列で使用することはできません。何をすべきか?
文字参照を返す代わりに、次のインターフェイスを使用してラッパー オブジェクトを返すことができます。
class CharRef { public: operator char() const; CharRef & operator=(文字); };
変換演算子はchar()
、文字列に格納されている文字のコピーを返すだけです。ただし、ラッパーに代入するとoperator=(char)
、参照カウントが 1 より大きい場合、文字列に強制的に内部コピーが実行され、代わりにそのコピーが変更されます。
ラッパーの実装は、たとえば、文字と文字列へのポインターを保持する場合があります (おそらく、文字列の実装の一部)。
変換が自然で、副作用がない場合、有用です。int
たとえば、 からへの自動変換が不適切であると主張する人は誰もいdouble
ないでしょう。たとえば、混乱を招くような特殊なケースを考え出すことができたとしても (誰もできるかどうかわかりません)。
Microsoft からCString
への変換はconst char *
信じられないほど便利であることがわかりましたが、他の人が同意しないことはわかっています。で同様の機能が見られてもかまいませんstd::string
。