首先呢,要明白一点儿,NULL 是一个无类型的东西,而且是一个宏。而宏这个东西,从 C++ 诞生开始,就是 C++ 之父嗤之以鼻的东西,他推崇尽量避免宏。
在C++标准中,我们可以见到一个词语叫做 null pointer constant
1. 其实在**C++11**标准前,是只承认**0**为**null pointer constant **的。所以,在**C++**中,我们也经常能听到一个说法,就是赋予 **null pointer**,应该是使用 **0**,而非 **NULL**。而 这个词语
1. 在**C++11**发布后,**nullptr pointer constant**再添了一个成员,就是**nullptr**。
注意:
1. **nullptr**与 **NULL**本质不同的是,**nullptr**是有类型的(放了在**stddef**头文件中),类型是 **typdef decltype(nullptr) nullptr_t**;
1. 如果编译器支持**nullptr**,请一定使用 **nullptr **!
nullptr 出现原因:
nullptr **的出现背景,其实是很简单,就是关于重载这个问题
void f(void*){
}
void f(int){
}
int main(){
f(0); // what function will be called?
}
引入了 nullptr ,这个问题就得到了真正解决,会很顺利的调到 void f (void*) 这个版本
优点:
nullptr 有类型后,还能做什么呢?那就是可以捕获异常了。
int main()
{
try
{
throw nullptr;
}
catch(nullptr_t)
{
}
}
你扔一个 NULL 试试?看他应该用什么收,正是因为没有类型,所以就要用它的宏定义的本质类型。你扔一个 0 试试?那就也不是所谓的空指针类型了,就是要用 int 什么的来收了。所以,推崇 nullptr是有道理的,我们在编译器实现 nullptr的时候考虑了非常非常多的细节,还有很多你们可能一直用不到的情况,我们都要用来测试,目的就是保障开发者的使用。
再次那句话,如果你的编译器支持nullptr,请一定使用 nullptr!
缺点:
好了,nullptr 是有类型的,叫做 nullptr_t,这给我们编译器实现带来了诸多要考虑的东西,举点儿例子
union U
{
long i;
nullptr_t t;
};
int main()
{
U u;
u.i = 3;
printf("%ld\n",(long)u.t); // What it is? 0 or 3?
}
那么这是应该符合 union 语意还是 nullptr 的语意呢?
这在标准中是没有说的,我们也为此争论了非常久。
当然在我们编译器的实现还是保持了 nullptr 的语意,结果是 0。