Modern C++之nullptr
引言
nullptr
的目的看起来是为了代替NULL
,因为在以前,C++总是把NULL
和0
当作是一样的东西,具体实现需要看编译器是如何定义NULL
的,有的是直接定义为0
,有的是当成((void*)0)
。
在C++里面,二级指针(**
)是不允许将void*
隐式转换为其他类型的。但是如果编译器中将NULL
定义为((void*)0)
,那么下面的代码是可以成立的
char *ch = NULL; // no error
在上面的代码中,不允许void*
隐式转换的C++必须将NULL
定义为0
。这样的话就会存在一个问题,会让C++的重载
功能令人困惑。
具体的例子如下所示,定于一个foo
函数
void foo(char*);
void foo(int);
然后通过foo(NULL)
掉用这个函数,会直接调用 foo(int)
函数,这样的执行逻辑违背了我们的直觉;
解决办法
为了解决C++中NULL
和0
的区别,C++引入了nullptr
关键字,其类型是nullptr_t
,nullptr可以被隐式转换成任何指针类型或者成员指针类型,并且可以和他们进行相等与否的比较
示例代码:
#include <iostream>
#include <type_traits>
void foo(char*)
{
std::cout << "Hello NULL" << std::endl;
}
void foo(int)
{
std::cout << "Hello INT" << std::endl;
}
int main()
{
if (std::is_same<decltype(NULL), decltype(0)>::value)
std::cout << "NULL == 0" << std::endl;
if (std::is_same<decltype(NULL), decltype((void*)0)>::value)
std::cout << "NULL == (void*)0" << std::endl;
if (std::is_same<decltype(NULL), decltype(nullptr)>::value)
std::cout << "NULL == nullptr" << std::endl;
foo(0); //将会调用foo(int)
foo(NULL); //还是会调用foo(int)
foo(nullptr); //将会调用foo(char*)
return 0;
}
输出结果:
NULL == 0
Hello INT
Hello INT
Hello NULL
从上面的输出结果我们可以看出,nullptr
和NULL
以及0
是不相同的。个人觉得还是养成使用nullptr
的习惯。