ホームページ > バックエンド開発 > C++ > C の Null ポインターで非仮想メンバー関数を呼び出すと機能する場合があるのはなぜですか?

C の Null ポインターで非仮想メンバー関数を呼び出すと機能する場合があるのはなぜですか?

DDD
リリース: 2024-12-13 16:58:10
オリジナル
668 人が閲覧しました

Why Does Calling a Non-Virtual Member Function on a Null Pointer in C   Sometimes Work?

C の落とし穴 : Null ポインターで非仮想クラス メンバーにアクセスする

C では、null で非仮想メンバー関数を呼び出すポインタは予期せず機能し、興味深いパズルを引き起こす可能性があります。興味深いコード スニペットを通じて、この動作を詳しく見てみましょう。

class Foo {
public:
    virtual void say_virtual_hi() {
        std::cout << "Virtual Hi";
    }

    void say_hi() {
        std::cout << "Hi";
    }
};

int main() {
    Foo* foo = 0;
    foo->say_hi(); // Works well
    foo->say_virtual_hi(); // Crashes the app
    return 0;
}
ログイン後にコピー

パズルの説明

仮想メソッドと非仮想メソッドの呼び出しに使用されるさまざまなメカニズムから混乱が生じます。 .

  • 仮想メソッド: 呼び出す関数を決定するには vtable ルックアップが必要ですが、null ポインターには有効なオブジェクトが関連付けられていないため失敗します。
  • 非仮想メソッド: 直接コンパイルされます。 this ポインタ (オブジェクト参照) を隠しパラメータとして渡す関数呼び出しとして。

指定されたコードでは、非仮想メソッド Say_hi() は、明示的に this ポインターを逆参照することはなく、null ポインター逆参照エラーを回避します。これは本質的に、値によって渡されるパラメーターを使用した関数呼び出しと同等です。

void Foo_say_hi(Foo* this);

Foo_say_hi(foo);
ログイン後にコピー

未定義の動作

技術的には、任意の関数 (非仮想も含む) を呼び出します。 null ポインターは C では未定義の動作です。ただし、一部のコンパイラ実装は、上記の非仮想関数呼び出しなど、特定のシナリオに対して明確に定義された動作を提供する場合があります。

注意

予期しない動作のように見える場合もありますが、便利ですが、それに依存するのは危険であり、ベストプラクティスではありません。予期せぬ予測不可能な結果を​​招く可能性があるため、null ポインターでクラス メンバーにアクセスすることは常に避けてください。

以上がC の Null ポインターで非仮想メンバー関数を呼び出すと機能する場合があるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート