c++中如何使用nullptr_c++ nullptr与NULL的区别【详解】

12次阅读

NULLptr是c++11起唯一推荐的空指针字面量;NULL本质是整型常量0或0L,易导致重载歧义、模板推导失败,并触发编译器警告。

c++中如何使用nullptr_c++ nullptr与NULL的区别【详解】

在 C++11 及之后的版本中,nullptr 是唯一推荐的空指针字面量;用 NULL 或整数字面量(如 0)表示空指针,不仅语义模糊,还可能引发函数重载歧义和模板推导错误。

为什么不能继续用 NULL

NULL 在绝大多数标准库实现中被定义为 00L(即整型常量),不是指针类型。这会导致几个典型问题:

  • 传给重载函数时可能意外匹配 int 版本而非 void* 版本
  • 在模板中(如 std::function 构造、std::make_unique)无法正确推导指针类型
  • 静态分析工具或编译器(如 Clang 的 -Wzero-as-null-pointer-constant)会发出警告
void foo(int x) { std::cout << "intn"; } void foo(char* p) { std::cout << "ptrn"; } 

foo(NULL); // 输出 "int" —— 不是你想要的! foo(nullptr); // 输出 "ptr" —— 正确绑定到指针重载

nullptr 的类型和使用限制

nullptr 的类型是 std::nullptr_t,它可隐式转换为任意原始指针类型(int*void* 等),但不能转换为整数类型(如 intlong),也不能赋值给非指针类型变量。

  • ✅ 合法:int* p = nullptr;void* v = nullptr;auto x = nullptr;(x 类型为 std::nullptr_t
  • ❌ 非法:int i = nullptr;if (nullptr == 42) {...}std::vector v = {nullptr};
  • ⚠️ 注意:nullptr 不能用于算术运算(nullptr + 1 编译失败),也不能解引用(*nullptr 是未定义行为)

在模板和智能指针中必须用 nullptr

现代 C++ 中,std::unique_ptrstd::shared_ptr 和容器算法(如 std::lower_bound)都依赖类型精确性。NULL 会破坏模板参数推导。

立即学习C++免费学习笔记(深入)”;

std::unique_ptr p1 = nullptr;     // ✅ OK // std::unique_ptr p2 = NULL;      // ❌ error: no viable conversion 

std::map m; m.find(nullptr); // ❌ 编译失败:key_type 是 string,不能用 nullptr 比较 // 但若你写成 m.find(std::string()), 就是另一回事了 —— 这里凸显的是类型安全,不是 nullptr 的错

更关键的是,像 std::Thread 构造函数接受可调用对象,若误传 NULL,可能被当作 int 而非空函数指针,导致静默错误。

跨平台与兼容性提醒

如果你的项目仍需支持 C++98/03 编译器(如极老的嵌入式工具链),nullptr 不可用,此时只能用 0 并配合注释说明意图。但只要能用 C++11,就绝不该再定义自己的 NULL 宏或沿用旧头文件里的 #define NULL 0

另外,nullptr 不是宏,不参与预处理;它是一个关键字,因此 sizeof(nullptr) 是合法的(通常等于 sizeof(void*)),而 sizeof(NULL) 结果取决于其定义(可能是 sizeof(int))。

text=ZqhQzanResources