nullptr 是类型安全的空指针字面量,类型为 std::nullptr_t,可隐式转换为任意指针类型,但不转换为整数类型,从而避免 NULL 在重载中的二义性问题。
nullptr 是 C++11 引入的关键字,其类型是 std::nullptr_t,能隐式转换为任意指针类型,但**不会隐式转换为整数类型**。这直接解决了 NULL 在函数重载时的二义性问题。
常见错误现象:
void func(int) { std::cout << "int\n"; }
void func(char*) { std::cout << "ptr\n"; }
func(NULL); // 调用 func(int),不是预期的 ptr 版本
func(nullptr); // 正确调用 func(char*)
NULL 通常定义为 0 或 ((void*)0),在 C++ 中本质是整数或不兼容的 void* 类型nullptr 的类型明确、唯一,编译器可据此做精确匹配nullptr
NULL 不是语言关键字,而是头文件中定义的宏(如 #define NULL 0 或 #define NULL ((void*)0)),具体展开取决于实现和包含的头文件(、 等)。
NULL 常被展开为 0,导致它和整数字面量完全等价((void*)0) 的处理可能违反 C++ 标准(void* 不能隐转为其他指针))时,NULL 行为更不可控在需要显式类型信息的上下文中,nullptr 能让编译器准确推导指针意图;而 NULL 可能触发整数分支或推导失败。
立即学习“C++免费学习笔记(深入)”;
使用场景示例:
auto p = nullptr; // p 类型是 std::nullptr_t
auto q = NULL; // q 类型是 int(如果 NULL 定义为 0)
templatevoid take_ptr(T*);
take_ptr(nullptr); // OK:T 被推导为任意类型
take_ptr(NULL); // 错误:无法从 int 推导出 T*
nullptr 初始化智能指针(std::unique_ptr p = nullptr; )是标准写法constexpr 上下文中,nullptr 是字面量常量,NULL 不一定满足要求nullptr,比如 static_assert(std::is_same_v);
除了维护极老的 C++03 代码(且不打算升级标准),没有理由继续使用 NULL。它的“兼容性”代价远高于收益。
NULL 发出 -Wzero-as-null-pointer-constant 警告NULL → nullptr
nullptr 在所有 C++11 兼容编译器中语义完全一致;NULL 则不然真正容易被忽略的是:有些团队在头文件里自定义 #define NULL nullptr,看似省事,实则掩盖了历史代码中对 NULL 的整数误用——这种宏掩盖比直接删掉更危险。