C++基础:指针空值(nullptr)

         初始化指针是将其指向一个“空”位置,比如0。由于大多数计算机系统不允许用户程序写地址为0的内存空间,倘若程序无意中对该指针所指地址赋值,通常在运行时就会导致程序退出。虽然程序退出并非什么好事,但这样一来错误也容易被程序员找到。因此,在大多数代码中,我们通常能看见的指针初始化的语法如下:

int *my_ptr=0;

int *my_ptr=NULL;

一个关于函数重载的示例:

C++基础:指针空值(nullptr)_第1张图片

     引起该问题的元凶是字面常量0的二义性,在c++98标准中,字面常量0的类型既可以是一个整型,也可以是一个无类型指针(void*)。如果程序员想在代码清单中调用fun(char*)版本的话,则必须像随后的代码一样,对字面常量0进行强制类型转换((char*)0)并调用,否则编译器总是会优先将0看做是一个整型常量。

       在C++11新标准中,出于兼容性考虑,字面常量0的二义性并没有被消除。但标准还是为二义性给出了新的答案,就是nullptr。在C++11标准中,nullptr是一个所谓“指针空值类型”的常量。指针空值类型被命名为nullptr_t,事实上,我们可以在支持nullptr的头文件(cstddef)中找出如下定义:

typedef decltype(nullptr) nullptr_t;

       可以看到,nullptr_t的定义方式非常有趣,与传统的先定义类型,再通过类型申明值得做法完全相反(充分利用了decltype的功能),可以发现在现有的编译器情况下,使用nullptr_t的时候,必须#include(#include有些头文件也会间接#include),而nullptr则不用,可能是由于nullptr是关键字,而nullptr_t是通过推导而来的缘故。   

简单而言,由于nullptr是有类型的,且仅可以被隐式转化为指针类型。

C++基础:指针空值(nullptr)_第2张图片

       可以发现,在改为使用nullptr之后,用户能够准确表达自己的意图,在书写C++11代码想使用NULL的时候,将NULL替换为nullptr,能够获得更健壮的代码。

nullptr和nullptr_t 

       C11标准不仅定义了指针空值常量nullptr,还定义了其指针空值类型nullptr_t,也就表示了指针空值类型并非仅有nullptr一个实例。通常情况下,也可以通过nullptr_t来申明一个指针空值类型的变量。

        除去nullptr及nullptr_t以外,C++中还存在各种内置类型。C++标准严格规定了数据间的关系,大体上常见的规则简单地列在了下面:

所有定义为nullptr_t类型的数据都是等价的,行为也完全一致。

nullptr_t类型数据可以隐式转换成任意一个指针类型。

nullptr_t类型数据不能转换为非指针类型,即使使用下面的方式也不可以;

reinterpret_cast()
int main()
{
    int a = nullptr;  //error
    int* p = nullptr;//ok
    char* cp = nullptr;//ok
    return 0;
}

 nullptr_t类型数据不适用于算术运算表达式;

nullptr_t类型数据可以用于关系运算表达式,但仅能与nullptr_t类型数据或者指针类型数据进行比较,当且仅当关系运算符为==,<=,>=等时,返回true。

注意:

       (1)nullptr是C11新引入的关键字,是一个所谓“指针空值类型”的常量,在C++程序中直接使用;

       (2)在C11中,sizeof(nullptr)和sizeof((void*)0)所占的字节数相同,都为(4或者8)

       (3)为了提高代码的健壮性,在后续表示指针空值时,建议最好使用nullptr.

你可能感兴趣的:(c++,开发语言)