ホームページ >バックエンド開発 >C++ >仮想関数の呼び出しは失敗するのに、非仮想関数の呼び出しは NULL ポインターで成功するのはなぜですか?

仮想関数の呼び出しは失敗するのに、非仮想関数の呼び出しは NULL ポインターで成功するのはなぜですか?

Susan Sarandon
Susan Sarandonオリジナル
2025-01-03 20:43:41531ブラウズ

Why Does a Non-Virtual Function Call Succeed on a NULL Pointer While a Virtual Function Call Fails?

NULL ポインターでのクラス メンバーへのアクセス: 異常と説明

提供された C コード スニペットでは、関数呼び出しが非仮想メソッドはオブジェクト ポインタが NULL であっても成功しましたが、仮想関数呼び出しによりアプリケーションがクラッシュしました。この奇妙な行動は、2 つの基本的な疑問を引き起こします:

1.非仮想メソッドは NULL ポインターでどのように動作しますか?

仮想関数呼び出しとは異なり、非仮想関数呼び出しでは vtable ルックアップが必要ありません。コンパイラは、関数呼び出しを、実行される特定の関数を指すマシンコード命令に直接変換します。関数には、関数が呼び出されるオブジェクトへのポインタが隠しパラメータとして渡されます。

指定されたコードでは、関数 Say_hi() は Foo クラスのメンバーを参照しません。したがって、 this ポインタを逆参照する必要なく実行できます。基本的に、say_hi() の呼び出しは次と同等です。

void Foo_say_hi(Foo* this);
Foo_say_hi(foo); // where foo is NULL

関数はオブジェクトのメンバーへのアクセスを試みないため、NULL ポインターの逆参照という未定義の動作は発生しません。

2.オブジェクト foo はどこに割り当てられますか?

提供されたコードでは、foo は Foo* 型のローカル変数として宣言されています。特定のメモリ割り当てが与えられていないため、他のローカル変数と同様に、main 関数のスタックに割り当てられる可能性が高くなります。ただし、foo に格納されている値は NULL ポインターであり、Foo 型の有効なオブジェクト インスタンスを指していないことを示しています。

以上が仮想関数の呼び出しは失敗するのに、非仮想関数の呼び出しは NULL ポインターで成功するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。