首頁 >後端開發 >C++ >為什麼在 C 中呼叫空指標上的非虛擬成員函數有時會起作用?

為什麼在 C 中呼叫空指標上的非虛擬成員函數有時會起作用?

DDD
DDD原創
2024-12-13 16:58:10660瀏覽

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

C 中的陷阱:存取空指標上的非虛擬類別成員

在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來決定要呼叫的函數,對於空指標來說失敗,因為它們沒有與其關聯的有效物件。
  • 非虛擬方法: 直接編譯作為函數調用,並將 this 指標(物件引用)作為隱藏參數傳遞。

在給定的程式碼中,非虛擬方法 say_hi() 從不明確取消引用 this 指針,從而繞過空指針取消引用錯誤。它本質上相當於具有按值傳遞參數的函數呼叫:

void Foo_say_hi(Foo* this);

Foo_say_hi(foo);

未定義行為

從技術上講,呼叫任何函數(甚至非虛擬)空指標是C 中未定義的行為。然而,某些編譯器實作可能會為特定場景提供明確定義的行為,例如上面的非虛函數呼叫。

注意

雖然意外的行為可能看起來雖然方便,但依賴它是有風險的,而且不是最佳實踐。始終避免透過空指標存取類別成員,因為這可能會導致意外且不可預測的結果。

以上是為什麼在 C 中呼叫空指標上的非虛擬成員函數有時會起作用?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn