0 NULL nullptr浅析

来源:互联网 发布:淘宝联盟机器人免费版 编辑:程序博客网 时间:2024/05/29 15:35

关于0NULLnullptr的区别

NULL的定义,其定义在cstddef文件中如下:

#ifndef NULL

#define NULL

#endif

NULL是用宏实现定义的空指针常量,在C中的定义为  #define NULL((void *0

专门用来定义空指针的,C++ 为了兼容C中的老版本NULLC是强类型语言,处理老版本的兼容问题时,必须强转,不然会报错),作了预处理操作,你可以将此看做定义如下:

#ifdef _cplusplus

#define NULL 0

#else

#define NULL ((void *)0)

#endif

C++  11 起 ,#define NULL 0改为了#define NULL nullptr   nullptr虽然是个宏,你完全可以当作C的定义 (void *0  个人感觉就是C++0和 (void *0进行了区分,当然区分开了,多个类型检查,相当于细化了指针初始化的检查而已)

所以如果使用NULL 就和直接使用nullptr相同,当然C++建议使用零值整数字面量(如  int * p = 0),或为std::nullptr_t类型纯右值 (如:int *p = nullptr,关键词nullptr指代指针字面量。它是std::nullptr_t类型的纯右值。存在从nullptr到任何指针类型及任何指向成员指针类型的隐式转换。

上面提到的std::nullptr_t cstddef中的定义如下:

 using nullptr_t = decltype(nullptr);  typedef void* nullptr_t;

即空指针类型,有了这个空指针类型就可以将空指针作为函数参数来重载函数,此时需要注意,因NULL的定义过于复杂,其(void*0的定义适合任意指针函数,所以重载时会出现重定义问题

 

void print(int *p)

{

cout << "hello int" << endl;

}

void print(double *p)

{

cout << "hello double" << endl;

}

void print(std::nullptr_t p) //这里的类型可以看做 void *

{

cout << "hello nullptr_t" << endl;

}

使用 int *p = NULL或nullptr时,调用print(p),直接调用第一个选项

使用 double *p = NULL或nullptr时,调用print(p),直接调用第二个选项

使用 std::nullptr_t p = nullptr时,调用print(p),直接调用第三个选项

没错你可能已经发现了,第三个重载只能调用std::nullptr_t,类型,不会去隐式的调用其他的类型,即便值相同。

 

如果开发为了快速好看好维护,初始化指针的时候还是尽量使用nullptr,不要使用0 或者 null,因为后两者在赋值的时候就相当于0值赋值,赋值给指针或者基本类型都没有问题,容易影响他人阅读代码。

 int *p = 0;不如  int *p =NULL;看的直接

Int *p = NULL;又不如 int *p = nullptr;来的安全 (强类型检查本身就是一种安全的措施之一)。