• Greedysky:C++ 建议用 nullptr 而不是 NULL


    前言

           在C语言中,我们常常用NULL作为指针变量的初始值,而在C++中,却不建议你这么做。

    NULL是什么

           在《C++ NULL,0》一文中,我们已经知道了在C中NULL是什么,在C的头文件中,通常定义如下:

    1
    #define NULL ((void*)0)

           但是在C++中,它是这样定义的:

    1
    #define NULL 0

           或者你可以在stddef.h看到完整的这段:

    1
    2
    3
    4
    5
    6
    #undef NULL
    #if defined(__cplusplus)
    #define NULL 0
    #else
    #define NULL ((void *)0)
    #endif

           也就是说,在C++中,NULL不过也是0罢了,把它当成空指针只是一个无可奈何的选择罢了。
           那么为什么在C++和C中不一样呢?因为C++中不能将void ✱类型的指针隐式转换成其他指针类型,从下面的例子可以看出来:

    1
    2
    3
    4
    5
    6
    7
    #include<iostream>
    int main(void)
    {
    char p[] = "12345";
    int *a = (void*)p;
    return 0;
    }

           编译运行:

    1
    2
    3
    4
    $ g+ -o null null.cpp
    null.cpp: In function 'int main()':
    null.cpp:5:17: error: invalid conversion from 'void*' to 'int*' [-fpermissive]
    int *a =(void*)p;

           所以不能将NULL定义为(void*)0。

    nullptr

           nullptr并非整型类别,甚至也不是指针类型,但是能转换成任意指针类型。nullptr的实际类型是std:nullptr_t。

    为什么该使用nullptr

           回到最开始的问题,为什么作为指针的语义,我们应该使用nullptr,而不是NULL。请看下面的代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    #include<iostream>
    using namespace std;
    void test(void *p)
    {
    cout<<"p is pointer "<<p<<endl;
    }
    void test(int num)
    {
    cout<<"num is int "<<num<<endl;
    }
    int main(void)
    {
     
    test(NULL);
    return 0;
    }

           编译运行:

    1
    2
    3
    4
    $ g++ -o test test.cpp
    main.cpp: In function ‘int main()’:
    main.cpp:16:14: error: call of overloaded ‘test(NULL)’ is ambiguous
    test(NULL);

           很不幸,编译报错了,提示我们有二义性,按照《重载函数匹配规则》,两个都可以匹配,因此最终报错。
           但是如果我们使用nullptr却不会:

    1
    test(nullptr);

           除了这点之外,在C++模板中它还有更好的表现。看下面的代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    #include<iostream>
    using namespace std;
    template<typename Type1,typename ptrType>
    void test(Type1 fun,ptrType ptr)
    {
    /*do something*/
    fun(ptr);
    return;
    }
    void fun(int *val)
    {
    cout<<"fun"<<endl;
    }
    int main(void)
    {
    test(fun,NULL);
    return 0;
    }

           编译报错了:

    1
    2
    main.cpp:8:8: error: invalid conversion from ‘long int’ to ‘int*’ [-fpermissive]
    fun(ptr);

           很显然NULL被推导为long int,而不是空指针,因而导致函数类型不匹配而报错。但是如果我们用nullptr就不会有上面的问题。

    总结

           如果你想表示空指针,那么使用nullptr,而不是NULL。
           注:nullptr在C++ 11中才出现。

    https://greedysky.github.io/2019/11/08/C++%20%E5%BB%BA%E8%AE%AE%E7%94%A8%20nullptr%20%E8%80%8C%E4%B8%8D%E6%98%AF%20NULL/

  • 相关阅读:
    图片上传-下载-删除等图片管理的若干经验总结3-单一业务场景的完整解决方案
    图片上传-下载-删除等图片管理的若干经验总结2
    HDU 1195 Open the Lock
    HDU 1690 Bus System
    HDU 2647 Reward
    HDU 2680 Choose the best route
    HDU 1596 find the safest road
    POJ 1904 King's Quest
    CDOJ 889 Battle for Silver
    CDOJ 888 Absurdistan Roads
  • 原文地址:https://www.cnblogs.com/findumars/p/14169973.html
Copyright © 2020-2023  润新知