當類的指標被賦值為NULL時,類的哪些成員還可以被該指標呼叫
轉自:https://blog.csdn.net/xiaoluer/article/details/53337292
該問題源自於一道面試題,題目如下所示:
看如下程式碼,請問能不能編譯通過?如果能編譯通過能不能執行成功?並說明原因
-
class test
-
{
-
public:
-
int fun(){return 1;};
-
};
-
int main ()
-
{
-
test *t = NULL;
-
int res = t->fun();
-
return 0;
-
}
好的,我們現在先來分析這道題目,初一看,該程式碼應該可以編譯通過,但是執行肯定不會過,因為t是NULL了嘛,怎麼還能再呼叫成員函式呢。
現在我們把這段程式碼貼到VS裡,編譯,執行,斷點,發現沒報錯,一切正常,res值為1...
好神奇!
通過查詢一些資料,我發現:
因為函式在類裡面是獨立於類存在的,而且不佔用類的空間,在程式編譯的時候就已經把函式的地址分配好了,因此,只要有這麼一個物件,不管他指向NULL還是非NULL,都是可以呼叫該函式的,也不會出錯。
那好,既然這樣,我們再來看下面這段程式碼:
-
class test
-
{
-
public:
-
test() {m_num = 0;};
-
int fun1() {return 1;};
-
static int fun2() {return 2;};
-
virtual int fun3() {return 3;};
-
int fun4() { return m_num;};
-
private:
-
int m_num;
-
};
-
int main ()
-
{
-
test *t = NULL;
-
int res1 = t->fun1();
-
int res2 = t->fun2();
-
int res3 = t->fun3();
-
int res4 = t->fun4();
-
return 0;
-
}
放到編譯器中,fun1,fun2可以正常執行,fun3,fun4執行出錯,這又是為什麼呢?
fun1上面已經分析過了,可以執行沒問題;
fun2是靜態函式,本身就不屬於類,所以跟類的指標沒有關係,可以執行,也沒有問題;
fun3是虛擬函式,而虛擬函式是通過虛擬函式表來實現的,而虛擬函式表是存在於物件中的,物件為NULL了,自然就無法訪問了;
fun4是呼叫了類的成員變數,而成員變數也同樣是存在於類的物件中的,為NULL的的物件沒有了成員變數的儲存空間,也無法訪問。
以上是對該問題相對錶層的分析,要想進一步瞭解該問題,建議看一下關於“__thiscall”的解釋,可以參考如下博文:
http://blog.csdn.net/yc_8301/article/details/1814744
我也會在後續的文章中專門對該問題做一個分析,敬請關注。