C++ nullptr和NULL区别 C++空指针安全使用建议【规范】
技术百科
冰火之心
发布时间:2026-01-27
浏览: 次 C++中NULL本质是整数0,非指针类型,易导致函数重载错误;应使用C++11引入的类型安全关键字nullptr,它为std::nullptr_t类型,可隐式转换为任意指针但不转整数,支持正确重载、模板推导和显式空指针比较。
NULL 在 C++ 中本质是整数 0,不是指针类型
很多老代码里写 int* p = NULL;,看着没问题,但编译器其实把它当成了 int* p = 0;。这在函数重载场景下会出问题:void foo(int) 和 void foo(char*) 同时存在时,foo(NULL) 会意外调用 foo(int),而不是你期望的指针版本。
原因在于:C++ 标准规定 NULL 是实现定义的宏,常见实现是 #define NULL 0 或 #define NULL 0L,始终是整型常量。
- 不推荐在 C++11 及以后使用
NULL表示空指针 - 若需兼容旧代码,确保头文件中未自行重定义
NULL -
NULL在 C 头文件(如
)中定义,C++ 中应优先用标准空指针字面量
nullptr 是类型安全的空指针字面量
nullptr 是 C++11 引入的关键字,类型为 std::nullptr_t,能隐式转换为任意指针类型,但不会转成整数类型。这意味着它能正确参与函数重载、模板推导和 auto 类型推导。
例如:auto p = nullptr; 推导出 std::nullptr_t,而 auto q = NULL; 推导出 int —— 这直接影响后续赋值和比较行为。
- 所有新代码必须用
nullptr替代NULL初始化或比较指针 - 不能对
nullptr执行算术运算(如nullptr + 1),编译直接报错,比运行时崩溃更早暴露问题 - 与
sizeof、typeid等操作符配合良好,语义清晰
判断空指针时避免隐式转换陷阱
写 if (p == nullptr) 是安全的;但写 if (p == 0) 或 if (!p) 虽然通常可行,却隐藏了类型风险。尤其在模板或泛型代码中,!p 可能触发用户自定义的 operator!,而非指针判空逻辑。
更隐蔽的问题出现在容器查找中:比如 std::map,用 m.find(0) 会因类型不匹配导致编译失败(0 是 int,不是 int*),而 m.find(nullptr) 可行。
- 统一用
p == nullptr或p != nullptr做显式空指针比较 - 禁用
if (p)/if (!p)风格(除非团队明确约定且静态检查覆盖) - 在模板参数、容器键类型、SFINAE 场景下,
nullptr是唯一可安全传递的空指针字面量
跨平台和遗留系统中的实际妥协点
极少数嵌入式编译器(如某些 ARM GCC 4.7 旧版本)或严格 C++03 环境不支持 nullptr。此时不应退回到 NULL,而应采用兼容性封装:
#ifdef __cplusplus11
#define SAFE_NULLPTR nullptr
#else
#define SAFE_NULLPTR 0
#endif但注意:这种宏仅用于初始化(int* p = SAFE_NULLPTR;),不可用于比较或模板实参——后者在 C++03 下本就不支持泛型空指针语义。
- 真正需要 C++03 兼容时,优先升级工具链,而非妥协语义
- 禁止在头文件中无条件
#define NULL nullptr,会破坏 C 头文件包含行为 - 第三方库若内部用
NULL,无需修改;但你的新代码与之交互时,仍应传nullptr(只要接口接受指针类型)
最易被忽略的是:即使用了 nullptr,也不能替代对指针生命周期的管理。悬空指针、释放后使用、多线程竞态等问题,nullptr 一个都拦不住——它只解决“怎么写空”这个语法层问题,不解决“什么时候该为空”这个逻辑层问题。
# 的是
# 看着
# 成了
# 出现在
# 而非
# 什么时候
# 就不
# 工具
# auto
# c++
# 隐式转换
# if
# int
# void
# 函数重载
# 泛型
# 实参
# 区别
# 指针
# 接口
# 线程
# NULL
# define
# operator
# 多线程
# 封装
# 头文件
# map
# 指针类型
# 隐式
# char
# 空指针
# 整型
# 整数类型
# 常量
# 转换为
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- Linux如何使用Curl发送请求_Linux下A
- mac怎么退出id_MAC退出iCloud账号与A
- php怎么下载安装后设置错误日志_phpini l
- mac怎么右键_MAC鼠标右键设置与触控板手势技巧
- Win11时间格式怎么改成12小时制 Win11时
- 如何在 Python 中将 ISO 8601 时间
- c# Task.ConfigureAwait(tr
- Python安全爬虫设计_IP代理池与验证码识别策
- PHP主流架构如何做单元测试_工具与流程【详解】
- Win11如何设置开机自动联网 Win11宽带连接
- C++如何使用std::transform批量处理
- Win11怎么恢复出厂设置_Win11重置此电脑保
- Windows电脑如何截屏?(四种快捷方法)
- Mac如何与安卓手机传文件_Mac和Android
- php嵌入式多设备通信怎么实现_php同时管理多个
- php转mp4怎么设置帧率_调整php生成mp4视
- 如何使用正则表达式精确匹配最多含一个换行符的 st
- 企业SEO优化选择网站建设模板的技巧
- 如何有效拦截拼接式恶意域名的垃圾信息
- Win11怎么关闭触控板_Win11笔记本禁用触摸
- 如何在Golang中写入XML文件_生成符合规范的
- c# 服务器GC和工作站GC的区别和设置
- 如何快速验证Golang安装是否成功_运行go v
- Windows任务计划服务异常原因_任务调度失败的
- c++怎么编写动态链接库dll_c++ __dec
- Python变量绑定机制_引用模型解析【教程】
- Linux怎么查找死循环进程_Linux系统负载分
- Python项目维护经验_长期演进说明【指导】
- 如何在Golang中捕获结构体方法错误_Golan
- php8.4如何配置ssl证书_php8.4htt
- php订单日志怎么在swoole写_php协程sw
- php增删改查需要哪些扩展_开启mysqli或pd
- php中作用域操作符能访问私有静态属性吗_访问权限
- Win11怎么更改文件夹图标_自定义Win11文件
- Python网络异常模拟_测试说明【指导】
- 如何在 Go 中正确反序列化多个同级 XML 元素
- Linux如何使用grep搜索文件内容_Linux
- c++的位运算怎么用 与、或、异或、移位操作详解【
- Python多进程教程_multiprocessi
- Python邮件系统自动化教程_批量发送解析与模板
- 如何理解Go指针和内存分配关系_Go Pointe
- Win11快速助手怎么用_Win11远程协助连接教
- Win11怎么自动隐藏任务栏_Win11全屏显示设
- Python字符串处理进阶_切片方法解析【指导】
- Win11屏幕亮度突然变暗怎么解决_自动变暗问题处
- 如何在包含多值的列中精准搜索指定演员?
- Win11怎么更改计算机名_Windows11系统
- Win11怎么更改任务栏位置_修改注册表将Win1
- php怎么连接数据库_MySQL数据库连接的基础代
- Windows10系统怎么查看运行时间_Win10


QQ客服