C++ 11 新特性 类型安全的空指针常量nullptr

C++11 引入的 nullptr 是一个专门用于表示空指针的关键字。

它的核心目的非常明确:彻底解决 C++98 中 NULL(本质是整数 0)带来的类型歧义问题,提供类型安全的空指针表示。

在 C++11 之前,我们用 NULL0 表示空指针,但它们在编译器眼里其实是整数。nullptr 的出现,让"空指针"终于有了属于自己的身份。

下面我将从语法、核心优势、底层机制及使用限制四个方面为你详细介绍。

1. 基本语法

nullptr 的用法非常简单,它可以直接赋值给任何指针类型。

cpp 复制代码
int* p1 = nullptr;      // 初始化 int 指针
char* p2 = nullptr;     // 初始化 char 指针
void* p3 = nullptr;     // 初始化 void 指针

// 它的类型是 std::nullptr_t (定义在 <cstddef> 中)
std::nullptr_t np = nullptr; 

2. 核心优势:为什么要用 nullptr

🛡️ 消除函数重载的歧义(最核心痛点)

在 C++98 中,NULL 通常被定义为 0。当你重载了一个接受 int 和一个接受 指针 的函数时,传入 NULL 会发生什么?编译器会优先匹配 int 版本,这往往违背了程序员的初衷。

  • C++98(歧义/错误):

    cpp 复制代码
    void func(int x) { cout << "调用了 int 版本" << endl; }
    void func(char* p) { cout << "调用了 指针版本" << endl; }
    
    func(NULL); // 输出:"调用了 int 版本" (因为 NULL 是 0)
    // 程序员本意是想传空指针,结果却调用了整数函数!
  • C++11(明确):

    cpp 复制代码
    func(nullptr); // 输出:"调用了 指针版本"
    // nullptr 只能转换为指针类型,编译器不再犹豫
🚫 类型安全:禁止转换为整数

nullptr 是一个纯指针概念,它不能隐式转换为整数类型。这防止了将空指针误用为数字的愚蠢错误。

cpp 复制代码
int x = nullptr; // ❌ 编译错误!
int y = NULL;    // ✅ 合法(但在现代 C++ 中不推荐),y 变为 0
🧩 模板推导更精准

在模板编程中,使用 NULL 会导致类型推导为 int,而 nullptr 能正确推导为指针类型或 std::nullptr_t

cpp 复制代码
template<typename T>
void printType(T t) { /* ... */ }

printType(NULL);    // T 被推导为 int
printType(nullptr); // T 被推导为 std::nullptr_t 或 指针类型

3. 底层机制:std::nullptr_t

nullptr 不是一个宏,也不是整数,它是一个字面量 ,其类型是 std::nullptr_t

  • 定义typedef decltype(nullptr) nullptr_t;
  • 转换规则std::nullptr_t 类型的值可以隐式转换为任何 原始指针类型(如 int*, void*)和成员指针类型。
  • 不转换 :它不能转换为整数类型。

4. 对比总结表

特性 0 NULL (C++98) nullptr (C++11)
本质类型 int int (通常是 0) std::nullptr_t
指针语义 模糊(既是数字也是指针) 模糊(宏定义,本质是数字) 明确(纯指针)
重载匹配 匹配 int 函数 匹配 int 函数 匹配 指针 函数
类型安全 低(可赋给 int) 低(可赋给 int) 高(不可赋给 int)
推荐程度 ❌ 绝不用于指针 ❌ 不推荐 唯一推荐

5. 避坑指南

  1. 不要混用 :在 C++11 及以后的代码中,永远不要再用 NULL ,全部替换为 nullptr

  2. 智能指针兼容nullptr 可以完美用于智能指针的初始化和重置。

    cpp 复制代码
    std::shared_ptr<int> sp = nullptr; // 合法
    sp = nullptr; // 合法,释放资源并置空
  3. 比较操作 :指针与 nullptr 的比较是安全的。

    cpp 复制代码
    if (p == nullptr) { ... } // 推荐写法
    if (!p) { ... }           // 也可以,但语义不如前者明确

一句话总结:
nullptr 是 C++ 类型安全的一块重要拼图。它用专用的类型 解决了通用的数字 0 带来的混乱。记住口诀:"指针为空用 nullptr,告别 NULL0!"

相关推荐
H Journey3 小时前
C++11 新特性 右值引用与移动语义 (Rvalue References & Move Semantics)
c++11·右值引用
量子炒饭大师21 小时前
【C++11】Cyber骇客的 亡骸剥离与右值重构 ——【右值引用 与 移动语义】(附带完整代码解析)
java·c++·重构·c++11·右值引用·移动语义
H Journey2 天前
C++ 11 新特性 基于范围的for循环
c++·c++11·for循环
小此方3 天前
Re:思考·重建·记录 现代C++ C++11篇 (二) 右值引用与移动语义&引用折叠与完美转发
开发语言·c++·c++11·现代c++
量子炒饭大师4 天前
【C++ 11】Cyber骇客 最后的一片净土 ——【C++11的 简单介绍 + 发展历史】历史唯物主义者带你理顺C++发展的由来
c++·dubbo·c++11
小此方4 天前
Re:思考·重建·记录 现代C++ C++11篇 (一) 列表初始化&Initializer_List
开发语言·c++·stl·c++11·现代c++
kpl_205 天前
智能指针(C++)
c++·c++11·智能指针
2301_789015628 天前
C++11新增特性:可变参数模板、lambda表达式、function包装器、bind绑定、defult和delete
c语言·开发语言·c++·算法·c++11·万能引用
2301_789015628 天前
C++11新增特性:列表初始化&左值引用&右值引用&万能引用&移动构造&移动赋值&引用折叠&完美转发
c语言·开发语言·c++·c++11