原文链接 Understanding nullptr in C++
译者注:
- nullptr 是 C++11 为了解决NULL的歧义问题而引入的新特性,表示空指针常量.
- 原文作者是 Utkarsh Trivedi,发布网站是GeeksforGeeks.
考虑下面的C++程序,它暴露了一些NULL的问题
// C++ program to demonstrate problem with NULL
// 说明NULL问题的C++程序
#include
using namespace std;
// function with integer argument
// 形参是整形的函数
// 译者注:不清楚为什么原作者将函数的返回值写为int,译者觉得应该改为void(下同)
int fun(int N) { cout << "fun(int)"; }
// Overloaded function with char pointer argument
// 形参是char指针的重载函数
int fun(char* s) { cout << "fun(char *)"; }
int main()
{
// Ideally, it should have called fun(char *),
// but it causes compiler error.
// 理想情况下, 它应该调用 fun(char*), 但是实际情况下会导致编译错误.
fun(NULL);
}
输出:
error: call of overloaded ‘fun(NULL)’ is ambiguous
NULL 一般被定义为 (void )0
, 也就是说允许将NULL转换为整形. 所以调用fun(NULL)
函数变得模棱两可(译者注:编译器不知道该调用哪个函数).
// This program compiles (may produce warning)
// 该程序成功编译(可能产生警告)
#include
int main()
{
int x = NULL; // 译者注: 为了验证是否可以将NULL转换为整形
}
nullptr
是怎样解决问题的?在上述程序中,如果用nullptr代替NULL,得到的结果是fun(char*)
nullptr 是一个关键字,可以用在NULL出现的任意地方.跟NULL相同,nullptr可以和隐式转换任意指针类型并且和其进行比较.与NULL不同的是,它不能隐式转换为整形和与整形比较
// This program does NOT compile
// 程序不能编译
#include
int main()
{
int x = nullptr; // 如上所述,nullptr不能转换为整形
}
输出:
[Error] cannot convert ‘std::nullptr_t’ to ‘int’ in initialization
顺便说一下(As a side note), nullptr 可以转换为布尔类型
// This program compiles
// 该程序成功编译
#include
using namespace std;
int main()
{
int *ptr = nullptr;
// Below line compiles
// 下面的代码也可以编译
if (ptr) { cout << "true"; }
else { cout << "false"; }
}
输出:
false
当我们比较两个简单的指针时,有很多地方不明确,但是两个nullptr_t类型的值之间的比较就有章可循:用<=
和>=
比较返回true
,用>
和<
比较会返回false
;nullptr和任意指针类型用==
和!=
比较,如果指针是空或者非空的,那么会分别返回true
和false
.(译者注: 可以参考之前NULL的用法)
// C++ program to show comparisons with nullptr
// 展示和nullptr比较的c++程序
#include
using namespace std;
// Driver program to test behavior of nullptr
// 测试nullptr特性的主程序
int main()
{
// creating two variables of nullptr_t type
// i.e., with value equal to nullptr
// 开两个nullptr_t类型的变量,也就是说值和nullptr相等
nullptr_t np1, np2;
// <= and >= comparison always return true
// <= 和 >= 比较总是返回true
if (np1 >= np2)
cout << "can compare" << endl;
else
cout << "can not compare" << endl;
// Initialize a pointer with value equal to np1
// 用 np1 初始化一个指针
char *x = np1; // same as x = nullptr (or x = NULL
// will also work) 与 x = nullptr (或者 x = NULL也可行)相同
if (x == nullptr)
cout << "x is null" << endl;
else
cout << "x is not null" << endl;
return 0;
}