首先呢,要明白一点儿,NULL 是一个无类型的东西,而且是一个宏。而宏这个东西,从 C++ 诞生开始,就是 C++ 之父嗤之以鼻的东西,他推崇尽量避免宏

    C++标准中,我们可以见到一个词语叫做 null pointer constant

    1. 1. 其实在**C++11**标准前,是只承认**0**为**null pointer constant **的。所以,在**C++**中,我们也经常能听到一个说法,就是赋予 **null pointer**,应该是使用 **0**,而非 **NULL**。而 这个词语
    2. 1. 在**C++11**发布后,**nullptr pointer constant**再添了一个成员,就是**nullptr**。

    注意:

    1. 1. **nullptr**与 **NULL**本质不同的是,**nullptr**是有类型的(放了在**stddef**头文件中),类型是 **typdef decltype(nullptr) nullptr_t**;
    2. 1. 如果编译器支持**nullptr**,请一定使用 **nullptr **!


    nullptr 出现原因:
    nullptr **的出现背景,其实是很简单,就是关于重载这个问题

    1. void f(void*){
    2. }
    3. void f(int){
    4. }
    5. int main(){
    6. f(0); // what function will be called?
    7. }

    引入了 nullptr ,这个问题就得到了真正解决,会很顺利的调到 void f (void*) 这个版本



    优点:
    nullptr 有类型后,还能做什么呢?那就是可以捕获异常了。

    1. int main()
    2. {
    3. try
    4. {
    5. throw nullptr;
    6. }
    7. catch(nullptr_t)
    8. {
    9. }
    10. }

    你扔一个 NULL 试试?看他应该用什么收,正是因为没有类型,所以就要用它的宏定义的本质类型。你扔一个 0 试试?那就也不是所谓的空指针类型了,就是要用 int 什么的来收了。所以,推崇 nullptr是有道理的,我们在编译器实现 nullptr的时候考虑了非常非常多的细节,还有很多你们可能一直用不到的情况,我们都要用来测试,目的就是保障开发者的使用。
    再次那句话,如果你的编译器支持nullptr,请一定使用 nullptr

    缺点:

    好了,nullptr 是有类型的,叫做 nullptr_t,这给我们编译器实现带来了诸多要考虑的东西,举点儿例子

    1. union U
    2. {
    3. long i;
    4. nullptr_t t;
    5. };
    6. int main()
    7. {
    8. U u;
    9. u.i = 3;
    10. printf("%ld\n",(long)u.t); // What it is? 0 or 3?
    11. }

    那么这是应该符合 union 语意还是 nullptr 的语意呢?
    这在标准中是没有说的,我们也为此争论了非常久。
    当然在我们编译器的实现还是保持了 nullptr 的语意,结果是 0