static_cast
C スタイルまたは単純な関数スタイルのキャストよりも関数を優先する必要があると聞きました。これは本当ですか? なぜですか?
ベストアンサー1
主な理由は、従来の C キャストでは、、、、と呼ばれるものを区別しないからです。static_cast<>()
これら4つは完全に異なります。reinterpret_cast<>()
const_cast<>()
dynamic_cast<>()
Astatic_cast<>()
は通常安全です。言語には有効な変換があるか、またはそれを可能にする適切なコンストラクタがあります。継承されたクラスにキャストダウンする場合のみ、少しリスクがあります。言語外部の手段 (オブジェクト内のフラグなど) によって、オブジェクトが実際に主張する子孫であることを確認する必要があります。dynamic_cast<>()
結果がチェックされるか (ポインター)、または起こりうる例外が考慮されるか (参照) が安全です。
一方、A reinterpret_cast<>()
(または a ) は常に危険です。コンパイラーに次のように伝えます。「信じてください。これは a のようには見えません(これは変更可能ではないように見えます) が、実際は変更可能です」。const_cast<>()
foo
最初の問題は、大規模で分散したコードを調べてすべてのルールを知らなければ、C スタイルのキャストでどれが発生するかを判断することがほぼ不可能であるということです。
次のように仮定しましょう:
class CDerivedClass : public CMyBase {...};
class CMyOtherStuff {...} ;
CMyBase *pSomething; // filled somewhere
さて、これら 2 つは同じ方法でコンパイルされます。
CDerivedClass *pMyObject;
pMyObject = static_cast<CDerivedClass*>(pSomething); // Safe; as long as we checked
pMyObject = (CDerivedClass*)(pSomething); // Same as static_cast<>
// Safe; as long as we checked
// but harder to read
ただし、ほぼ同じコードを見てみましょう。
CMyOtherStuff *pOther;
pOther = static_cast<CMyOtherStuff*>(pSomething); // Compiler error: Can't convert
pOther = (CMyOtherStuff*)(pSomething); // No compiler error.
// Same as reinterpret_cast<>
// and it's wrong!!!
ご覧のとおり、関係するすべてのクラスについて十分な知識がなければ、2 つの状況を区別する簡単な方法はありません。
2 番目の問題は、C スタイルのキャストを見つけるのが難しすぎることです。複雑な式では、C スタイルのキャストを見つけるのが非常に難しい場合があります。本格的な C++ コンパイラ フロントエンドがなければ、C スタイルのキャストを見つける必要がある自動化ツール (検索ツールなど) を作成することは事実上不可能です。一方、「static_cast<」または「reinterpret_cast<」を検索するのは簡単です。
pOther = reinterpret_cast<CMyOtherStuff*>(pSomething);
// No compiler error.
// but the presence of a reinterpret_cast<> is
// like a Siren with Red Flashing Lights in your code.
// The mere typing of it should cause you to feel VERY uncomfortable.
つまり、C スタイルのキャストはより危険であるだけでなく、すべてを見つけて正しいことを確認するのがはるかに困難になります。