[解決済み] なぜ (int)x ではなく static_cast<int>(x) を使うのですか?
質問
という話を聞いたことがあります。
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言語スタイルのキャストはより危険なだけでなく、それらが正しいことを確認するためにすべてを見つけるのはかなり難しいということです。
関連
-
[解決済み】非静的メンバ関数への参照を呼び出す必要がある
-
[解決済み】c++でstd::vectorを返すための効率的な方法
-
[解決済み] 非静的データメンバの無効な使用
-
[解決済み] intをenumにキャストするにはどうすればよいですか?
-
[解決済み] using namespace std;」はなぜバッドプラクティスだと言われるのですか?
-
[解決済み] static_cast, dynamic_cast, const_cast, reinterpret_cast はいつ使うべきですか?
-
[解決済み] mallocの結果はキャストするのですか?
-
[解決済み] C#でenumからint値を取得する
-
[解決済み] なぜ、オブジェクトそのものではなく、ポインタを使用しなければならないのですか?
-
[解決済み】なぜJavaの+=, -=, *=, /=複合代入演算子はキャスティングを必要としないのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】LLVMで暗黙のうちに削除されたコピーコンストラクタの呼び出し
-
[解決済み] エラーが発生する。ISO C++は型を持たない宣言を禁じています。
-
[解決済み】浮動小数点例外エラーが発生する: 8
-
[解決済み】エラー:free(): 次のサイズが無効です(fast)。
-
[解決済み】システムが指定されたファイルを見つけられませんでした。
-
[解決済み】Enterキーを押して続行する
-
[解決済み】エラー。引数リストに一致するコンストラクタのインスタンスがない
-
[解決済み] レギュラーキャスト vs スタティックキャスト vs ダイナミックキャスト [重複]の比較
-
[解決済み] C++形式のキャストでintをcharにキャストする [重複] [重複
-
[解決済み] C#でenumからint値を取得する