Skip to content

空指针字面量 ​

#纯右值

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