c 11中nullptr(與NULL的區別)

2021-07-12 00:54:08 字數 2482 閱讀 7339

首先呢,要明白一點兒,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...