空指針爲什麼能調用成員函數?(轉載)

發現了一個空指針調用函數成功的例子,很奇怪就查了一下資料,如下:

舉個簡單的例子,假如有如下的一段代碼:

class MyClass
{
public:
    int i;
    void hello()
    {
        printf("hello\n");
    }
    void print()
    {
        printf("%d\n", i);
    }
};
void main()
{
    MyClass* pmy = NULL;
    pmy->hello(); 
}

看上面的這段代碼,似乎很詭異。 用一個空指針調用成員函數,簡直是天大的錯誤,可以遺憾的是,卻是可行的,至少對於上面的這段程序來說,不會照成錯誤。
爲什麼?
    其實,這並不是十分神祕的問題,假如你曾經使用過C封裝結構的話,對於這個問題,是十分好理解的。
    在類初始化的時候,編譯器會將它的函數分配到類的外部,當然這也包括靜態成員函數,這樣的做法,主要是爲了節約內存,這也是爲什麼靜態函數可以在對象初始化之前運行的原因。
    大家知道,每個對象,都有一個指向自己的this指針,這個指針的值,將會因爲對象的不同而不同,它的作用主要就是用來區分不同的對象,這樣你就可以根據它來訪問不同的對象的成員變量。

    編譯器編譯後的成員函數的第一個參數是this指針,通過this指針引用數據成員及調用其它成員函數。

    我們main函數中的hello函數並沒有使用類中的任何成員變量,所以,它也就不會用到this指針,此時的this指針是NULL。由於你調用的成員函數沒有使用到類的數據成員,所以即使傳入的this指針爲空,從而我們就可以沒有障礙的使用hello函數,然而相對的是,如果你在pmy->hello()之後接着調用pmy->print(),那麼將會報空指針錯誤,因爲這個函數試圖用this指針訪問成員變量i。

發佈了11 篇原創文章 · 獲贊 6 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章