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 = {}  

 

posted @ 2017-11-05 00:46  lsgxeva  阅读(2503)  评论(0编辑  收藏  举报