空指针字面量
#纯右值
cpp
nullptr- 关键字
nullptr是空指针字面量,表示一个不指向任何对象的指针。
基础用法
替代 NULL 和 0
用于指针变量的初始化和赋值,替代传统的
NULL和0。
cpp
int* ptr1 = nullptr; // 推荐用法
int* ptr2 = NULL; // 传统用法
int* ptr3 = 0; // 不推荐
// 检查指针是否为空
if (ptr1 == nullptr) {
// 处理空指针情况
}解决重载歧义问题
在函数调用中明确传递空指针,
nulltpr能避免重载歧义问题, 并且避免与整数类型的混淆。
cpp
void func(int* ptr) {
if (ptr != nullptr) {
*ptr = 42;
}
}
void func(int value) {
// 处理整数参数
}
int main() {
func(nullptr); // 明确调用指针版本
func(0); // 可能调用整数版本,产生歧义
func(NULL); // 可能调用整数版本,产生歧义
}bash
main.cpp: In function 'int main()':
main.cpp:16:9: error: call of overloaded 'func(NULL)' is ambiguous
16 | func(NULL); // 可能调用整数版本,产生歧义
| ~~~~^~~~~~确保模板编程中的类型安全
在模板函数和类中,
nullptr提供更好的类型推导和安全性。
cpp
template<class T>
constexpr T clone(const T& t) {
return t;
}
void g(int*) {
std::cout << "Function g called\n";
}
int main() {
g(nullptr); // ok
g(NULL); // ok
g(0); // ok
g(clone(nullptr)); // ok
g(clone(NULL)); // ERROR: NULL 可能会被推导成非"指针"类型
g(clone(0)); // ERROR: 0 会被推导成非"指针"类型
}当使用函数模板时, NULL 和 0 通过会被推导成非"指针"类型, 而 nullptr 可以避免这个问题:
bash
main.cpp:19:12: error: invalid conversion from 'int' to 'int*' [-fpermissive]
19 | g(clone(0)); // ERROR: 0会被推导成非"指针"类型
| ~~~~~^~~
| |
| int注意事项
类型推导和 std::nullptr_t
nullptr 的类型是 std::nullptr_t,一个可以 隐式 转换为任何指针类型的特殊类型。
cpp
#include <cstddef> // 包含 std::nullptr_t 的定义
void func(int*) {}
void func(double*) {}
void func(std::nullptr_t) {}
int main() {
auto ptr = nullptr; // ptr 的类型是 std::nullptr_t
func(nullptr); // 调用 std::nullptr_t 版本
func(ptr); // 调用 std::nullptr_t 版本
int* intPtr = nullptr;
func(intPtr); // 调用 int* 版本
double* doublePtr = nullptr;
func(doublePtr); // 调用 double* 版本
}与布尔类型的隐式转换
nullptr 可以隐式转换为 bool 类型,在条件判断中非常方便:
cpp
int* ptr = nullptr;
if (ptr) { // 等价于 if (ptr != nullptr)
// 指针非空
} else {
// 指针为空
}
bool isEmpty = (ptr == nullptr); // true