首页 > 编程笔记

C++ nullptr关键字的用法

在C语言中,为避免野指针的出现,通常使用 NULL 为指针赋值。

C语言中 NULL 的定义如下所示:

#define NULL ((void *)0)

由上述定义可知,NULL 是一个void*类型的指针,其值为 0。在使用 NULL 给其他指针赋值时,发生了隐式类型转换,即将 void* 类型指针转换为要赋值的指针类型。

NULL 的值被定义为字面常量 0,这样会导致指针在使用过程中产生一些不可避免的错误。例如,有两个函数,函数声明如下所示:
void func(int a,int *p);
void func(int a,int b);
在上述代码中,有两个重载函数 func(),如果在调用第一个 func() 函数时,传入的第二个参数为 0 或 NULL,则编译器总会调用第二个 func() 函数,即两个参数都是 int 类型的函数。这就与实际想要调用的函数相违背。

如果想要根据传入的参数成功调用相应的 func() 函数,则需要使用 static_cast 转换运算符将 0 强制转换,示例代码如下所示:
func(1,0);   //调用func(int a,int b)
func(1,static_cast<int *>(0));   //调用func(int a,int *p)
虽然使用 static_cast 转换运算符解决了此问题,但是这种方式极易出错,而且会增加代码的复杂程度。

为了修复上述缺陷,C++11 标准引入了一个新的关键字nullptr,nullptr 也表示空指针,可以为指针赋值,避免出现野指针。

但是,nullptr 是一个有类型的空指针常量,当使用 nullptr 给指针赋值时,nullptr 可以隐式转换为等号左侧的指针类型。

需要注意的是,nullptr 只能被转换为其他指针类型,不能转换为非指针类型。示例代码如下所示:
int* p = nullptr;   //正确
int x = nullptr;   //错误,nullptr不能转换为int类型
由于 nullptr 只能转换为其他指针类型,因此它能够消除字面常量 0 带来的二义性。

在调用 func() 函数时,如果传入 nullptr 作为第二个参数,则 func() 函数能够被正确调用。示例代码如下所示:
func(1,0);   //调用func(int a,int b)
func(1,nullptr);   //调用func(int a,int *p)

优秀文章