1. ホーム
  2. c++

[解決済み] なぜ (int)x ではなく static_cast<int>(x) を使うのですか?

2022-03-14 07:39:27

質問

という話を聞いたことがあります。 static_cast 関数は、C 言語スタイルや単純な関数スタイルのキャストよりも優先されるべきです。 これは本当ですか? なぜですか?

どのように解決するのか?

主な理由は、古典的な C 言語のキャストは、私たちが「Cast」と呼ぶものを区別していないからです。 static_cast<>() , reinterpret_cast<>() , const_cast<>() および dynamic_cast<>() . この4つは全く違うものです。

A static_cast<>() は通常、安全です。その言語には有効な変換方法があり、またそれを可能にする適切なコンストラクタがあります。唯一、ちょっと危険なのは、継承されたクラスにキャストダウンするときです。そのオブジェクトが実際にあなたが主張する子孫であることを、言語の外部の手段(オブジェクト内のフラグなど)で確認する必要があります。A dynamic_cast<>() は、結果を確認する(ポインタ)か、例外の可能性を考慮する(参照)限り、安全です。

A reinterpret_cast<>() (または 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言語スタイルのキャストはより危険なだけでなく、それらが正しいことを確認するためにすべてを見つけるのはかなり難しいということです。