zoukankan      html  css  js  c++  java
  • 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/

  • 相关阅读:
    CLSCompliantAttribute
    杂言
    批处理修改目录的隐藏属性
    unittest基本用法
    unittest跳过用例
    MySQL流程控制结构
    MySQL视图
    MySQL函数
    unittest断言 & 数据驱动
    PLSQL
  • 原文地址:https://www.cnblogs.com/findumars/p/14169973.html
Copyright © 2011-2022 走看看