原文链接🔗 Understanding nullptr in C++
译者注:
nullptr 是 C++11 为了解决NULL的歧义问题而引入的新特性,表示空指针常量.原文作者是 Utkarsh Trivedi,发布网站是GeeksforGeeks.考虑下面的C++程序,它暴露了一些NULL的问题
// C++ program to demonstrate problem with NULL // 说明NULL问题的C++程序 #include <bits/stdc++.h> 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<stdio.h> int main() { int x = NULL; // 译者注: 为了验证是否可以将NULL转换为整形 }在上述程序中,如果用nullptr代替NULL,得到的结果是fun(char*) nullptr 是一个关键字,可以用在NULL出现的任意地方.跟NULL相同,nullptr可以和隐式转换任意指针类型并且和其进行比较.与NULL不同的是,它不能隐式转换为整形和与整形比较
// This program does NOT compile // 程序不能编译 #include<stdio.h> 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<iostream> 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 <bits/stdc++.h> 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; }