引入nullptr的緣由,這個要從NULL提及。對於C和C++程序員來講,必定不會對NULL感到陌生。可是C和C++中的NULL卻不等價。NULL表示指針不指向任何對象,可是問題在於,NULL不是關鍵字,而只是一個宏定義(macro)。
c++
在C中,習慣將NULL定義爲void*指針值0:程序員
#define NULL (void*)0
但同時,也容許將NULL定義爲整常數0
函數
在C++中,NULL卻被明肯定義爲整常數0:
spa
// lmcons.h中定義NULL的源碼 #ifndef NULL #ifdef __cplusplus #define NULL 0 #else #define NULL ((void *)0) #endif #endif
根本緣由和C++的重載函數有關。C++經過搜索匹配參數的機制,試圖找到最佳匹配(best-match)的函數,而若是繼續支持void*的隱式類型轉換,則會帶來語義二義性(syntax ambiguous)的問題。指針
// 考慮下面兩個重載函數 void foo(int i); void foo(char* p) foo(NULL); // which is called?
若是咱們的編譯器是支持nullptr的話,那麼咱們應該直接使用nullptr來替代NULL的宏定義。正常使用過程當中他們是徹底等價的。
對於編譯器,Visual Studio 2010已經開始支持C++0x中的大部分特性,天然包括nullptr。而VS2010以前的版本,都不支持此關鍵字。
Codeblocks10.5附帶的G++ 4.4.1不支持nullptr,升級爲4.6.1後可支持nullptr(需開啓-std=c++0x編譯選項或者-std=c++11)
code
0(NULL)和nullptr能夠交換使用,以下示例:
對象
int* p1 = 0; int* p2 = NULL; int* p3 = nullptr; if(p1 == 0) {} if(p2 == 0) {} if(p3 == 0) {} if(p1 == nullptr) {} if(p2 == nullptr) {} if(p3 == nullptr) {} if(p1 == p2) {} if(p2 == p3) {} if(p1) {} if(p2) {} if(p3) {}
不能將nullptr賦值給整形,以下示例:
編譯器
int n1 = 0; // ok int n2 = NULL; //warning int n3 = nullptr; // error int n4 = (int)NULL; //ok int n5 = (int)nullptr; //error if(n1 == nullptr) {} // error if(n2 == nullptr) {} // error if(nullptr) {} // error nullptr = 0 // error
可見,nullptr要比NULL要求更加嚴格。源碼
上面提到的重載問題,使用nullptr時,將調用char*。
void foo(int) {cout << "int" << endl;} void foo(char*) {cout << "pointer" << endl;} foo(0); // calls foo(int) foo(nullptr); // calls foo(char*)
某些編譯器不支持c++11的新關鍵字nullptr,咱們也能夠模擬實現一個nullptr。
const class nullptr_t_t { public: template<class T> operator T*() const {return 0;} template<class C, class T> operator T C::*() const { return 0; } private: void operator& () const; } nullptr_t = {}; #undef NULL #define NULL nullptr_t