实习时公司的C++11白名单里有一条:使用 nullptr 代替 NULL 来表示空指针,不要使用 0 来表示空指针。也没有进一步的说明,简单查了一下做个记录。
在C++11以前我们一般用NULL来代表空指针,在C中,NULL通常被定义如下:1
2
3
4
5
6//定义
#define NULL ((void *)0)
//使用
int *i = NULL;
foo_t *f = NULL;
也就是说NULL实际上是一个void 的指针,然后吧void 指针赋值给int 和foo_t 的指针的时候,隐式转换成相应的类型。而如果换做一个C++编译器来编译的话是要出错的,因为C++是强类型的,void *是不能隐式转换成其他指针类型的,所以通常情况下,编译器提供的头文件会这样定义NULL:
1 | #ifndef NULL |
可见在C++中,0就是NULL, 问题在于,当遇到函数重载时:1
2
3
4
5
6
7
8
9
10
11
12void fun(int a) {
std::cout << "int";
}
void fun(int *a) {
std::cout << "ptr";
}
int main() {
fun(0);
fun(NULL);
}
结果是,函数都会调用参数为int的函数,这不是我们想要的,为了将两者区分开来,C++11引入了nullptr来表示空指针这个含义,把代码中的NULL替换为nullptr就可以调用指针那个函数。
nullptr可以自动转换为各种指针类型,但不会转换为整数类型,它也有自己的类型,是
结论: 如果使用 nullptr 初始化对象,就能避免 0 指针的二义性的问题。所以推荐使用nullptr来代表空指针。