C++中 0 與 NULL 與 nullptr之間的關系,nullptr_t 的實現


C++中 0 與 NULL 與 nullptr之間的關系,nullptr_t 的實現

 

來源 http://blog.csdn.net/Virtual_Func/article/details/49756913

參考了網上各種資料,理清楚了 0 與 NULL 以及 nullptr 的關系。

 

1. 從本質上

 1) 0是int型的字面值常量

 2) NULL 是預處理變量,定義在 cstdlib 中,其值是0

 3) nullptr 是 nullptr_t 類型的字面值。

 

2. cstdlib 中 NULL 的定義

 
  1. #ifdef __cplusplus  
  2.   
  3. #define NULL 0  
  4.   
  5. #else  
  6.   
  7. #define NULL ((void *)0)  
  8.   
  9. #endif  

 

之所以這樣定義的原因,是因為在C語言中,允許 void* 類型隱式轉換為任意指針類型,而C++中不允許這樣的強制類型轉換,但是可以為任意類型的指針賦0值,因此,在C++中將NULL 定義為0

 

3. 0 比 NULL 好

在網上的資料中,均是一致認為 0 比 NULL 好,因為很多可能會出錯的時候,使用 0 更直觀,如:

  1. void test(int i){ cout << "in int" << endl; }  
  2. void test(int * i){ cout << "in int *" << endl; }  
  3.   
  4. int main()  
  5. {  
  6.     test(0); //輸出 in int  
  7.     test(NULL); //輸出 in int  
  8. }  

此時,兩個函數調用均會調用參數為 int 的 test,使用 0 調動的版本看起來更加直觀,因為 0 本身是一個 int 類型的字面值常量,而會潛意識的認為 NULL 應該是一個指針類型,不利於查錯

 

4. nullptr 比 0 更好

nullptr 是 nullptr_t 類型的常量,而該類型定義了轉到任意指針類型的轉換操作符,同時不允許該類型的對象轉換到非指針類型,在上面的調用例子中,使用 nullptr,將會調用第二個函數,輸出 “in int*”,因為 nullptr被轉換為了int * ,符合我們通常的理解。對於nullptr_t 的類型可以定義如下: 

 
  1. class nullptr_t  
  2. {  
  3. public:  
  4.     template<class T>  
  5.     inline operator T*() const    //定義類型轉換操作符,使nullptr_t 可轉為任意非類成員指針類型  
  6.     { return 0; }  
  7.   
  8.       
  9.     //重載類型轉換操作符,使 nullptr_t 可以轉換為類 C 中任意的指針類型(數據成員指針/函數成員指針)      
  10.     //對類中數據成員的指針,T 將被推導為數據成員的類型 eg: int (X::*); 此時 T 為 int,C 為 X  
  11.     //對類中函數成員的指針,T 將被推導為函數成員的類型 eg: int (X::*)(int); 此時T 等效於: typedef int (T)(int)  
  12.     template<class C, class T>  
  13.     inline operator T C::*() const    
  14.     { return 0; }             
  15. private:                  
  16.     void operator&() const;  
  17. };  
  18.   
  19. const null_ptr nullptr = {}  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM