首先呢,要明白一點兒,null是乙個無型別的東西,而且是乙個巨集。而巨集這個東西,從c++誕生開始,就是c++之父嗤之以鼻的東西,他推崇盡量避免巨集。而在他的faq中,也有相應的乙個關於null與0的解釋,也談到了這一點兒。stroustrup: c++ style and technique在c++標準中,我們可以見到乙個詞語叫做null pointer constant,其實在c++11標準前,是只承認0為null pointer constant的。所以,在c++中,我們也經常能聽到乙個說法,就是賦予null pointer,應該是使用0,而非null。而nullptr pointer constant這個詞語在c++11發布後,終於再添了乙個成員,就是nullptr。而與null本質不同的是,nullptr是有型別的(放了在stddef標頭檔案中),型別是 typdef decltype(nullptr) nullptr_t; 而正是因為是有型別的,這給我們編譯器實現nullptr的時候帶來了更多細節的考慮,當然也給了使用者更多的保障,所以如果你的編譯器支援nullptr,請一定使用nullptr!
而nullptr的出現背景,其實是很簡單的,c++哲學上來說就是c++之父一直對null pointer沒有乙個正式的表示感到非常不滿,而更工程的來說,就是關於過載這個問題。
void f(void*)
void f(int)
int main()
而引入了nullptr,這個問題就得到了真正解決,會很順利的調到void f(void*)這個版本。
好了,真的以為nullptr就這樣了麼? 我前面說過了nullptr是有型別的,叫做nullptr_t,這給我們編譯器實現帶來了諸多要考慮的東西,不幸的話讓我們來舉點兒奇葩例子吧!
union u
;int main()
那麼這是應該符合union語意還是nullptr的語意呢?這在標準中是沒有說的,我們也為此爭論了非常久。當然在我們編譯器的實現還是保持了nullptr的語意,結果是0。
而nullptr有型別後,還能做什麼呢?那當然就是可以捕獲異常了。
int main()
catch(nullptr_t) }
你扔乙個null試試?看他應該用什麼收,正是因為沒有型別,所以就要用它的本質型別,比如long什麼的來說。你扔乙個0試試?那就也不是所謂的空指標型別了,就是要用int什麼的來收了。
所以,推崇nullptr是有道理的,我們在編譯器實現nullptr的時候考慮了非常非常多的細節,還有很多你們可能一直用不到的情況,我們都要用來測試,目的就是保障開發者的使用。再次那句話,如果你的編譯器支援nullptr,請一定使用nullptr!
1、為什要有nullptr
我們給乙個指標賦初值的時候一般這麼寫 file* fp = null;
這裡有個null的定義,一般情況下它是這麼定義的:
[cpp]
#ifdef __cplusplus
#define null 0
#else
#define null ((void *)0)
#endif
在c語言環境下,由於不存在函式過載等問題,直接將null定義為乙個void*的指標就可以完美的解決一切問題。
但是在c++環境下情況就變得複雜起來, 首先我們不能寫這樣的** file* fp = (void*)0; 將void*直接賦值給乙個指標是不合法的,編譯器會報錯。 我們只能這樣寫**
[cpp]
file* fp = (file*)0;
// or
file* fp = 0;
所以在c++下面,null就被直接定義為乙個整型 0。 在大多數情況下這並不會產生什麼問題,但是萬一有過載或者模板推導的時候,編譯器就無法給出正確結果了。比如下面的情形:
[cpp]
void call_back_process(ccobject* target, void* data);
bind(call_back_process, target, null); // error 函式型別是void* ,但是我們繫結的是乙個整型 0
2、 nullptr的應用場景:
如果我們的編譯器是支援nullptr的話,那麼我們應該直接使用nullptr來替代null的巨集定義。正常使用過程中他們是完全等價的。
3、模擬nullptr的實現:
某些編譯器不支援c++11的新關鍵字nullptr,我們也可以模擬實現乙個nullptr
[cpp] www.2cto.com
const
class nullptr_t_t
templateoperator t c::*() const
private:
void operator& () const;
} nullptr_t = {};
#undef null
#define null nullptr_t
C 11標準之NULL與nullptr比較
隨著c 11 標準的出現,c 的規範也越來越嚴謹,在減少語言二義性上,c 委員會確實做了很多努力。在過去,我們如果要表示乙個指標為空,我們條件反射肯定會這麼寫 int p null 然而啊,有沒有想過這是有問題的,比如下面的這段 include include using namespace std...
C 11新特性之 nullptr
我們知道在程式設計的世界裡,0有雙重的角色,可以表示整數零,也可以表示乙個空指標。在c語言中,通過預編譯巨集null,可以區分0表示的是零還是 void 0.但是,在c 的世界中,這樣是不可以的。c 中允許函式過載。例如 void foo char void foo int 如果把null定義為0,...
C 11 新特性 nullptr 學習
nullptr 出現的目的是為了替代 null。在某種意義上來說,傳統 c 會把 null 0 視為同一種東西,這取決於編譯器如何定義 null,有些編譯器會將 null 定義為 void 0 有些則會直接將其定義為 0。c 不允許直接將 void 隱式轉換到其他型別,但如果 null 被定義為 v...