400 8949 560

NEWS/新闻

分享你我感悟

您当前位置> 主页 > 新闻 > 技术开发

c++ nullptr与NULL区别_c++11空指针规范

发表时间:2026-01-01 00:00:00

文章作者:穿越時空

浏览次数:

NULL本质是整数0,重载时优先匹配int参数而非指针;nullptr是std::nullptr_t类型,只向指针隐式转换,确保类型安全。

函数重载时传 NULL 为什么常调错版本?

因为 NULL 本质是宏,C++ 中多数编译器定义为 0int 类型),不是指针。当存在两个重载函数时,编译器优先匹配整数参数——哪怕你本意是传空指针。

  • void func(int)void func(char*) 同时存在时:func(NULL) 会调用 func(int),而不是你预期的指针版本
  • func(nullptr) 则**一定**匹配 func(char*),因为 nullptr 的类型是 std::nullptr_t,只向指针类型隐式转换
  • VS、GCC、Clang 在 C++11+ 模式下行为一致,但老项目若混用 C 风格头文件(如 ),NULL 定义可能更混乱

模板推导中 NULL 会悄悄“变类型”?

是的。NULL 是整数,进模板后常被推成 int;而 nullptr 进模板永远是 std::nullptr_t,再由上下文决定转成什么指针——这才是你想要的语义。

  • auto x = NULL;x 类型是 int(危险!后续误当指针用就崩)
  • auto y = nullptr;y 类型是 std::nullptr_t,且能安全用于 int*std::string* 等任何指针上下文
  • 智能指针初始化也一样:std::unique_ptr p = NULL; 编译通过但语义错误;std::unique_ptr p = nullptr; 才是标准写法

能不能把 NULL 全局替换成 nullptr?要注意什么?

可以,但别用 IDE “全文件替换”一刀切——尤其注意 C 头文件和跨语言接口代码。

  • 纯 C++11+ 项目:直接全局搜索 = NULL(NULL)== NULL,替换成 = nullptr 等,基本安全
  • 含 C 代码或 extern "C" 接口时,NULL 可能被 C 编译器要求(比如系统 API 参数),此时保留 NULL 更稳妥
  • 宏定义里用到 NULL(如 #define SAFE_DELETE(p) do { delete p; p = NULL; } while(0)),建议改写为 p = nullptr,但需确认所有使用该宏的指针类型兼容
  • 检查构建日志:替换后若出现 error: cannot convert 'int' to 'xxx*' in assignment,说明某处 NULL 原本被当整数用了(比如数组索引),不能硬换

不升级到 C++11 就不能用 nullptr?

是的。nullptr 是 C++11 标准关键字,C++98/03 编译器(如旧版 VC6、GCC 4.1 以下)根本不认识它,会报 error: 'nullptr' was not declared in this scope

  • 若必须支持老标准,可用轻量模拟(非完全等价):
    const class nullptr_t {
    public:
      template operator T*() const { return 0; }
      template operator T C::*() const { return 0; }
    private: void operator&() const;
    } nullptr = {};
  • 但强烈不建议在生产环境手写模拟——它无法参与 SFINAE、不支持 decltype(nullptr)、与标准库智能指针交互可能出问题
  • 真正要长期维护的老项目,优先考虑升级工具链;临时兼容可加条件编译:#if __cplusplus >= 201103L 分支处理
C++11 之后,nullptr 不是“可选项”,而是类型安全的底线——它不解决新功能,但堵住了 NULL 留下的所有歧义入口。最易忽略的点是:**连 if (ptr == NULL) 这种看似无害的判断,都可能因宏展开或重载干扰,在复杂模板中引发静默类型退化**。

相关案例查看更多