1. 程式人生 > >C++ 空指標呼叫函式 靜態繫結

C++ 空指標呼叫函式 靜態繫結

首先看一段程式碼是否知道其正確還是錯誤。
class A{
public:
void print()
{
cout << "Hello" << endl;
}


};
void main()
{
A *a = NULL;
a.print();
}
問你程式是否正確執行,或者執行結果是什麼。
這就是一個典型的表示C++是一個靜態語言的特徵。可以闡明“靜態繫結”和“動態繫結”的區別。真正的原因是:因為對於非虛成員函式,C++這門語言是靜態繫結的。這也是C++語言和其它語言Java, Python的一個顯著區別。C++奉行的原則是能夠在編譯時候搞定的事情絕不拖到執行時搞定。我們的第一感覺是這個程式應該是錯的,然而事實卻是相反的。每個物件都有指向自己的this指標,指標的值會因為不同的物件不同而不同,用來區別不同的物件。這裡的this指標就是一個NULL。如果我們呼叫this指標的時候就會出錯。可是這個函式並沒有用到this指標就是簡單的輸出字串,這一過程在編譯階段就已經完成了。所以不會報錯。
但是對於C++。為了保證程式的執行時效率,C++的設計者認為凡是編譯時能確定的事情,就不要拖到執行時再查找了。所以C++的編譯器看到這句話會這麼幹:
1:查詢a的型別,發現它有一個非虛的成員函式叫print。(編譯器乾的)
2:找到了,在這裡生成一個函式呼叫,直接調A::print()。
所以到了執行時,由於print函式裡面並沒有任何需要解引用somenull指標的程式碼,所以真實情況下也不會引發segment fault。這裡對成員函式的解析,和查詢其對應的程式碼的工作都是在編譯階段完成而非執行時完成的,這就是所謂的靜態繫結,也叫早繫結。
正確理解C++的靜態繫結可以理解一些特殊情況下C++的行為。