空指針爲什麼能調用成員函數?

舉個簡單的例子,假如有如下的一段代碼:
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指針,這個指針的值,將會因爲對象的不同而不同,它的作用主要就是用來區分不同的對象,這樣你就可以根據它
來訪問不同的對象的成員變量。然而,我們main函數中的hello函數並沒有使用類中的任何成員變量,所以,它也就不會用到this指針,此時的this指針是NULL。從而
我們就可以沒有障礙的使用hello函數,然而相對的是,如果你在pmy->hello()之後接着調用pmy->print(),那麼將會報空指針錯誤,因爲這個函數試圖用this指針訪問成員變量i。
   就是這麼簡單。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章