C++ 11 新特性 类型安全的空指针常量nullpt
C11 引入的nullptr是一个专门用于表示空指针的关键字。它的核心目的非常明确彻底解决 C98 中NULL本质是整数 0带来的类型歧义问题提供类型安全的空指针表示。在 C11 之前我们用NULL或0表示空指针但它们在编译器眼里其实是整数。nullptr的出现让“空指针”终于有了属于自己的身份。下面我将从语法、核心优势、底层机制及使用限制四个方面为你详细介绍。1. 基本语法nullptr的用法非常简单它可以直接赋值给任何指针类型。int*p1nullptr;// 初始化 int 指针char*p2nullptr;// 初始化 char 指针void*p3nullptr;// 初始化 void 指针// 它的类型是 std::nullptr_t (定义在 cstddef 中)std::nullptr_t npnullptr;2. 核心优势为什么要用nullptr️ 消除函数重载的歧义最核心痛点在 C98 中NULL通常被定义为0。当你重载了一个接受int和一个接受指针的函数时传入NULL会发生什么编译器会优先匹配int版本这往往违背了程序员的初衷。C98歧义/错误voidfunc(intx){cout调用了 int 版本endl;}voidfunc(char*p){cout调用了 指针版本endl;}func(NULL);// 输出调用了 int 版本 (因为 NULL 是 0)// 程序员本意是想传空指针结果却调用了整数函数C11明确func(nullptr);// 输出调用了 指针版本// nullptr 只能转换为指针类型编译器不再犹豫 类型安全禁止转换为整数nullptr是一个纯指针概念它不能隐式转换为整数类型。这防止了将空指针误用为数字的愚蠢错误。intxnullptr;// ❌ 编译错误intyNULL;// ✅ 合法但在现代 C 中不推荐y 变为 0 模板推导更精准在模板编程中使用NULL会导致类型推导为int而nullptr能正确推导为指针类型或std::nullptr_t。templatetypenameTvoidprintType(T t){/* ... */}printType(NULL);// T 被推导为 intprintType(nullptr);// T 被推导为 std::nullptr_t 或 指针类型3. 底层机制std::nullptr_tnullptr不是一个宏也不是整数它是一个字面量其类型是std::nullptr_t。定义typedef decltype(nullptr) nullptr_t;转换规则std::nullptr_t类型的值可以隐式转换为任何原始指针类型如int*,void*和成员指针类型。不转换它不能转换为整数类型。4. 对比总结表特性0NULL(C98)nullptr(C11)本质类型intint(通常是 0)std::nullptr_t指针语义模糊既是数字也是指针模糊宏定义本质是数字明确纯指针重载匹配匹配int函数匹配int函数匹配指针函数类型安全低可赋给 int低可赋给 int高不可赋给 int推荐程度❌ 绝不用于指针❌ 不推荐✅唯一推荐5. 避坑指南不要混用在 C11 及以后的代码中永远不要再用NULL全部替换为nullptr。智能指针兼容nullptr可以完美用于智能指针的初始化和重置。std::shared_ptrintspnullptr;// 合法spnullptr;// 合法释放资源并置空比较操作指针与nullptr的比较是安全的。if(pnullptr){...}// 推荐写法if(!p){...}// 也可以但语义不如前者明确一句话总结nullptr是 C 类型安全的一块重要拼图。它用专用的类型解决了通用的数字 0带来的混乱。记住口诀“指针为空用nullptr告别NULL和0”