Modern C++之nullptr

引言

nullptr的目的看起来是为了代替NULL,因为在以前,C++总是把NULL0当作是一样的东西,具体实现需要看编译器是如何定义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++中NULL0的区别,C++引入了nullptr关键字,其类型是nullptr_tnullptr可以被隐式转换成任何指针类型或者成员指针类型,并且可以和他们进行相等与否的比较

示例代码:

#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

从上面的输出结果我们可以看出,nullptrNULL以及0是不相同的。个人觉得还是养成使用nullptr的习惯。

posted @ 2020-03-10 21:14  醉曦  阅读(227)  评论(0编辑  收藏  举报