nullptr 是 C++11 引入的空指针字面量,类型为 std::nullptr_t,仅隐式转换为指针或成员指针类型;不可赋给 int 或传入 printf 等可变参数函数,否则未定义行为;重载和模板推导中语义明确;智能指针支持直接初始化,容器 push_back(nullptr) 安全;跨平台需确保 C++11+ 标准;裸指针必须显式初始化为 nullptr 以避免未定义行为。

为什么 nullptr 不能直接赋给 int 或传给可变参数函数
因为 nullptr 是类型为 std::nullptr_t 的字面量,它隐式转换只对指针类型和成员指针类型有效。常见错误是写 printf("%p", nullptr) —— 这在 C++11+ 中行为未定义,printf 不认识 std::nullptr_t,会崩或输出乱码。
- 用
printf("%p", static_cast<void>(nullptr))</void>替代(C++11 起安全) - 函数重载时,
void f(int)和void f(void*)同时存在,f(nullptr)一定调用后者;但f(NULL)可能调前者(因NULL常定义为0或0L) - 模板推导中,
auto p = nullptr;推出std::nullptr_t,不是指针类型,别误当void*用
nullptr 在智能指针和容器中的实际写法
智能指针如 std::unique_ptr、std::shared_ptr 都支持用 nullptr 显式初始化或重置,这是最清晰的“空状态”表达。但要注意:容器(如 std::vector<:shared_ptr>></:shared_ptr>)存的是对象,不是裸指针,所以 push_back(nullptr) 没问题,但 push_back(NULL) 可能触发整型重载歧义。
-
std::unique_ptr<int> p = nullptr;</int>✅ 清晰、无歧义 -
p.reset();等价于p = nullptr;,但显式写= nullptr更易读 -
if (p == nullptr)比if (!p)更明确意图(尤其团队有 C 背景成员时) - 不要写
if (p.get() == nullptr)—— 多余,get()是为 C API 交互准备的,日常判断直接用p == nullptr
跨平台编译时 nullptr 的兼容性底线
nullptr 是 C++11 标准特性,所有现代编译器(GCC 4.6+、Clang 3.0+、MSVC 2010+)都支持。但如果你的项目仍需支持 VS2008 或 GCC 4.3 以下版本,就无法用 nullptr —— 此时必须用宏抽象:#define SAFE_NULLPTR 0 不行(类型不对),正确做法是条件编译或统一用 NULL 并接受歧义风险。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 检查编译器:GCC 用
__cplusplus >= 201103L,MSVC 用_MSC_VER >= 1600 - CMake 中可加
set(CMAKE_CXX_STANDARD 11)强制标准,避免部分旧项目默认用 C++98 - 头文件里不要写
using std::nullptr_t;—— 它不常用,且可能污染命名空间;需要时直接用std::nullptr_t
裸指针初始化漏写 nullptr 的典型后果
局部裸指针不初始化就用,值是随机的(野指针),if (p == nullptr) 判断永远为假,后续 delete p 或解引用直接 UB。这不是 nullptr 的问题,而是没用它兜底的习惯问题。
立即学习“C++免费学习笔记(深入)”;
- 所有裸指针声明后立即初始化:
int* p = nullptr;,哪怕后面马上赋值 - 类成员指针在构造函数初始化列表中设为
nullptr,别依赖默认值(C++ 中没有“默认为空指针”这回事) - 函数返回裸指针时,明确返回
nullptr表示失败,而不是return 0;或return NULL;(后者语义模糊) - 静态分析工具(如 Clang Static Analyzer、PVS-Studio)能捕获未初始化指针,但前提是代码写了
= nullptr—— 它们靠这个模式推断程序员的“空意图”
事情说清了就结束。真正难的不是记住 nullptr 怎么写,而是每次声明指针时,手指有没有条件反射地敲出 = nullptr。


















