C++里的nullptr为什么比NULL更安全?(强类型检查防止重载歧义)

11次阅读

NULLptr 是类型安全的空指针字面量,只能隐式转换指针类型而不会转为整数;NULL 是宏(常为0),在重载函数中易引发歧义匹配。

C++里的nullptr为什么比NULL更安全?(强类型检查防止重载歧义)

nullptr 是类型安全的空指针字面量

nullptrc++11 中被引入,本质是 std::nullptr_t 类型的纯右值,只能隐式转换为任意指针类型(包括成员指针),但**不会转换为整数类型**。而 NULL 通常是宏定义,比如 #define NULL 0#define NULL ((void*)0) —— 前者是 int,后者在 C++ 中不合法(C++ 禁止 void* 隐式转其他指针),所以实际编译器常退化为 00L

重载函数调用时避免歧义

当存在多个重载函数,参数分别是 intchar*(或任意指针)时,传 NULL 可能意外匹配 int 版本:

void foo(int) { std::cout << "intn"; } void foo(char*) { std::cout << "char*n"; } 

foo(NULL); // 输出 "int"(取决于 NULL 定义,但常见行为) foo(nullptr); // 编译错误?不,它只匹配 char → 输出 "char"(唯一可行转换)

这是因为 nullptr 不能转成 int,而 NULL(若为 0)是 int,优先匹配 int 重载。

模板推导和 auto 推导更可靠

NULL 初始化模板参数或 auto 变量,类型可能不是你想要的:

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

  • auto p = NULL;p 类型是 int(不是指针!)
  • auto p = nullptr;p 类型是 std::nullptr_t,后续赋值给任何指针都合法
  • 模板函数如 template void bar(T*); bar(NULL);T 推导失败(NULL 不是指针类型),而 bar(nullptr) 可正确推导出 T

与 sizeof、函数指针等场景的兼容性

nullptr 的大小始终与指针一致(sizeof(nullptr) == sizeof(void*)),且可直接赋值给函数指针:

void func() {} void (*fp)() = nullptr;  // 合法 // void (*fp)() = NULL;   // 若 NULL 是 0,则 error:cannot convert 'int' to 'void (*)()'

某些平台对 NULL 宏的实现不统一,尤其跨编译器或混用 C/C++ 头文件时,nullptr 彻底规避了宏展开和整数/指针二义性问题。

真正容易被忽略的是:即使项目已全面使用 nullptr,第三方 C 头文件里仍可能带 NULL 宏;若你在 C++ 中写 if (p == NULL),虽能编译,但已失去类型安全优势——这种写法应一律改为 p == nullptr 或更推荐的 !p

text=ZqhQzanResources