目录

一、背景与概述

二、NULL 的定义与问题

1. NULL 的定义

2. NULL 的问题

三、nullptr 的定义与优势

1. nullptr 的定义

2. nullptr 的优势

四、nullptr 与 NULL 的对比

五、实际应用场景

1. 初始化指针

2. 函数调用与重载

3. 条件判断

4. 模板与泛型编程

六、现代 C++ 的最佳实践

1. 优先使用 nullptr

2. 避免 NULL 的隐式转换

3. 兼容性处理

4. 统一代码风格

七、总结

八、示例代码

示例 1:nullptr 与 NULL 的区别

示例 2:nullptr 的类型安全性

示例 3:nullptr 在模板中的使用

C++从入门到入土学习导航_c++学习进程-CSDN博客


一、背景与概述

在 C++ 中,空指针的表示经历了从 NULLnullptr 的演变。NULL 是 C 语言遗留下来的宏定义,而 nullptr 是 C++11 引入的专门用于空指针的关键字。两者的区别主要体现在 类型安全函数重载可读性现代 C++ 实践 等方面。


二、NULL 的定义与问题

1. NULL 的定义

  • NULL 是一个宏,通常定义为 0(在 C++ 中)或 (void*)0(在 C 中),例如:
    #define NULL 0       // C++ 中常见定义
    #define NULL (void*)0 // C 中常见定义
  • 由于 NULL 是宏,其本质是一个整数常量(0)或无类型指针((void*)0)。

2. NULL 的问题

(1) 类型不安全
  • NULL 可以隐式转换为任何整数类型,可能导致意外行为:
    int i = NULL; // 合法,但语义不明确
  • 与指针类型混淆,可能导致函数重载歧义(见下文)。
(2) 函数重载歧义
  • 如果存在两个重载函数,一个接受整数参数,一个接受指针参数,使用 NULL 会调用整数版本:
    void func(int);   // 重载1
    void func(char*); // 重载2func(NULL); // 调用 func(int),因为 NULL 是 0
(3) 可读性差
  • NULL 的语义不明确,容易让开发者误认为它是一个整数而不是空指针。

三、nullptr 的定义与优势

1. nullptr 的定义

  • nullptr 是 C++11 引入的关键字,表示空指针,其类型为 std::nullptr_t
  • 它是一个专门用于表示空指针的右值常量,不能隐式转换为整数类型

2. nullptr 的优势

(1) 类型安全
  • nullptr 仅能赋值给指针类型,不会与整数混淆:
    int* p = nullptr; // 合法
    int i = nullptr;  // 错误:无法将 std::nullptr_t 转换为 int
(2) 解决函数重载歧义
  • nullptr 会明确匹配指针类型的函数重载:
    void func(int);   // 重载1
    void func(char*); // 重载2func(nullptr); // 调用 func(char*),匹配指针类型
(3) 提升代码可读性
  • int* p = nullptr; // 语义明确:p 是一个空指针
(4) 兼容性与泛型编程
  • nullptr 的类型 std::nullptr_t 可以隐式转换为任意指针类型,但在泛型编程中表现更稳定,减少类型推导错误。

四、nullptr 与 NULL 的对比

特性nullptrNULL
类型std::nullptr_t宏,通常为 0(C++)或 (void*)0(C)
类型安全性✅ 仅能赋值给指针类型❌ 可隐式转换为整数或其他类型
函数重载匹配✅ 明确匹配指针类型❌ 可能匹配整数类型
可读性✅ 语义明确❌ 可能引起歧义
推荐使用场景✅ C++11 及以上版本❌ 旧代码或 C 兼容性需求
隐式转换限制❌ 不能隐式转换为整数✅ 可隐式转换为整数
C 兼容性❌ C 不支持(C23 引入)✅ C 语言兼容

五、实际应用场景

1. 初始化指针

int* p1 = nullptr; // 推荐:C++11 及以上
int* p2 = NULL;    // 不推荐:旧代码或 C 兼容性

2. 函数调用与重载

void func(int);
void func(char*);func(nullptr); // 调用 func(char*)
func(NULL);    // 调用 func(int)

3. 条件判断

if (p == nullptr) {// 推荐:明确判断指针是否为空
}
if (p == NULL) {// 不推荐:语义不明确
}

4. 模板与泛型编程

template <typename T>
void process(T* ptr) {if (ptr == nullptr) {// 安全处理空指针}
}

六、现代 C++ 的最佳实践

1. 优先使用 nullptr

  • 在 C++11 及以上版本中,始终使用 nullptr 替代 NULL
  • nullptr 提供了更强的类型安全性和代码可读性。

2. 避免 NULL 的隐式转换

  • 避免将 NULL 赋值给非指针类型(如 int),否则会导致编译错误或运行时错误。

3. 兼容性处理

  • 在需要兼容旧代码或与 C 语言交互时,可以保留 NULL,但应逐步迁移到 nullptr

4. 统一代码风格

  • 在团队或项目中统一使用 nullptr,减少因 NULL 导致的潜在问题。

七、总结

  • nullptr 是 C++11 引入的现代空指针表示方式,解决了 NULL 在类型安全、函数重载和可读性上的问题。
  • 推荐始终使用 nullptr,除非必须兼容旧代码或与 C 语言交互。
  • 通过使用 nullptr,可以编写更安全、更清晰、更符合现代 C++ 标准的代码。

八、示例代码

示例 1:nullptr 与 NULL 的区别

#include <iostream>void func(int) {std::cout << "func(int)" << std::endl;
}void func(char*) {std::cout << "func(char*)" << std::endl;
}int main() {func(NULL);    // 输出: func(int)func(nullptr); // 输出: func(char*)return 0;
}

示例 2:nullptr 的类型安全性

#include <iostream>int main() {int* p1 = nullptr; // 合法int i = nullptr;   // 错误:无法将 std::nullptr_t 转换为 intreturn 0;
}

示例 3:nullptr 在模板中的使用

#include <iostream>template <typename T>
void process(T* ptr) {if (ptr == nullptr) {std::cout << "Pointer is null" << std::endl;}
}int main() {int* p = nullptr;process(p); // 输出: Pointer is nullreturn 0;
}

通过掌握 nullptrNULL 的区别,开发者可以编写更安全、更高效的现代 C++ 代码,避免因空指针导致的潜在问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/86471.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/86471.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/86471.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机存储器容量扩展设计实例解析

存储器容量扩充是《计算机组成原理》课程的重要知识点。讲解一个例题&#xff0c;以说明进行存储器容量扩充设计的方法。 题目&#xff1a;在32位计算机系统中&#xff0c;用8K16位的SRAM芯片组成一个64KB的存储器&#xff0c;已知起始地址为&#xff1a;6000 0000H。已知&…

转载-秒杀系统—1.架构设计和方案简介

转载&#xff1a; https://mp.weixin.qq.com/s?__bizMzg5MzY5NDM3MQ&mid2247490866&idx1&sn0081517454680c85e0ed23eda4e82df5&chksmc02ba5fef75c2ce8b0c7f54182f3bda539230c75d2d75ed2b514b93decc0ff0c5de548a35dc3&cur_album_id3548464749150224391&…

Kubernetes中的容器生命周期回调

在介绍Kubernetes容器生命周期回调前&#xff0c;展示一个案例。 有个私有化部署的项目需要跑一个redis用作缓存&#xff0c;因redis中的数据不需要持久化&#xff0c;选择在Kubernetes中通过deployment的方式部署&#xff0c;下面是deployment的代码片段&#xff0c; ......…

基于STM32的工业仓库环境智能监控系统设计

文章目录 一、前言1.1 项目介绍【1】项目开发背景【2】设计实现的功能【3】项目硬件模块组成【4】设计意义【5】市面上同类产品研究现状【6】摘要 1.2 设计思路1.3 系统功能总结1.4 开发工具的选择【1】设备端开发【2】上位机开发 1.5 模块的技术详情介绍【1】ESP8266-WIFI模块…

如何在 Manjaro Linux 上启用 AUR 仓库来安装软件包

Manjaro 是基于 Arch 的系统&#xff0c;是了解和学习 Arch Linux 命令的绝佳方式。它自带所有流行的桌面环境界面&#xff0c;无论是 XFCE 还是 Gnome 的爱好者&#xff0c;都可以在 Manjaro 中直接使用。 Manjaro 或 Arch Linux 的默认软件包管理器是 Pacman&#xff0c;我们…

有限上升时间信号的反射波形

有限上升时间信号的反射波形: 从上一节讨论中我们知道&#xff0c;阻抗不连续的点处&#xff0c;反射信号是入射信号的一个副本&#xff0c;并讨论了上升时间为0的信号的反射情况。这些规律对于上升时间不为0的信号同样适用&#xff0c;只不过入射信号和反射信号的叠加稍稍复杂…

Vue 3.4+ defineModel 全面详解 + 实战最佳实践

&#x1f31f; 前言&#xff1a;为什么要关注 defineModel&#xff1f; 过去我们在 Vue 组件中使用 v-model 时&#xff0c;常需要这样写&#xff1a; // 子组件 defineProps([modelValue]) defineEmits([update:modelValue])function update(val) {emit(update:modelValue, …

MySQL事物隔离级别详解

目录 事物隔离级别总结 实际情况演示 脏读&#xff08;未提交&#xff09; 避免脏读&#xff08;读已提交&#xff09; 不可重复读 可重复读 幻读 事物隔离级别总结 SQL标准定义了四种事物隔离级别&#xff0c;用来平衡事物的隔离性&#xff08;Isolation&#xff09;和…

【安卓开发】Kotlin入门教程

一、Kotlin 基础入门 1.1 Kotlin 简介 Kotlin 是一种由 JetBrains 开发的静态类型编程语言&#xff0c;运行在 Java 虚拟机上&#xff0c;也可以编译为 JavaScript 或原生代码。它于 2017 年被 Google 宣布为 Android 官方开发语言。 主要特点&#xff1a; 简洁&#xff1a;…

工业机器人保护气体节约方法

焊接在现代工业生产中作为一项关键技术&#xff0c;其效率和质量直接影响着产品的最终性能和生产成本。随着智能制造的不断推进&#xff0c;工业焊接机器人在自动化生产线中扮演着越来越重要的角色。焊接过程中的气体调节一直是一个技术难题&#xff0c;它直接关系到焊接质量的…

java中集合API

集合API 一、简述二、Collection&#xff08;1&#xff09;.List1.ArrayList&#xff1a;2. LinkedList &#xff08;2&#xff09; Set 三、Map1.HashMap2. TreeMap 三、Iterator接口Collections工具类1.对集合元素进行排序2.基于Comparator&#xff0c;自定义方法(内部类)进行…

Oracle 用户权限与对象权限详解

一、权限体系概述 Oracle 数据库的权限管理是保障数据安全的核心机制&#xff0c;主要分为系统权限&#xff08;System Privileges&#xff09; 和对象权限&#xff08;Object Privileges&#xff09; 两大类&#xff1a; 系统权限&#xff1a;赋予用户在数据库中执行特定操作…

kubectl get pods 时 “client-side throttling, not priority and fairness“ 原因初探

1. 问题起源 在kubernetes里&#xff0c;使用kubectl get pods 时&#xff0c;返回 I0508 05:43:04.655602 100742 request.go:668] Waited for 1.178494016s due to client-side throttling, not priority and fairness, request: GET:https://10.103.0.1:443/apis/cert-ma…

力扣网C语言编程题:位运算来解决 “寻找重复数”

一. 简介 前面两篇文章解决力扣网上"查找重复数"的题目&#xff0c;提供了三种思路&#xff1a;哈希表、二分法和快慢指针。文章如下&#xff1a; 力扣网C语言编程题&#xff1a;“寻找重复数”的两种思路-CSDN博客 力扣网C语言编程题&#xff1a;快慢指针来解决 …

3D视觉感知

目录 3D视觉感知任务 单目3D感知 单目3D物体检测 – 直接预测3D信息 单目3D物体检测 – 总结 单目深度估计 双目3D感知 多目3D感知 3D视觉感知任务  输入&#xff1a;单摄像头或多摄像头生成的图像数据  单张图像  图像序列  输出  稀疏&#xff1a…

es中常规的根据字段查询时走什么索引(说明:「常规的根据字段查询」不包含分词查询)

在Elasticsearch中&#xff0c;“常规的根据字段查询”且不涉及分词的查询&#xff08;如精确匹配、范围查询&#xff09;&#xff0c;主要依赖以下索引机制&#xff1a; 一、核心索引类型及适用场景 字段类型索引结构典型查询方式应用场景keyword倒排索引&#xff08;未分词…

MYSQL如何插入数据,效率会更高

在MySQL中&#xff0c;插入数据的效率可以通过多种方式逐步提升。以下是从简单到复杂的优化路径&#xff0c;帮助你逐步提高数据插入的性能&#xff1a; 一、基础插入&#xff1a;逐条插入 这是最基础的插入方式&#xff0c;适用于少量数据的插入操作。虽然简单&#xff0c;但…

Rabbitmq的五种消息类型介绍,以及集成springboot的使用

交换机类型 Fanout Exchange 扇型交换机&#xff0c;这个交换机没有路由键概念&#xff0c;就算你绑了路由键也是无视的。 这个交换机在接收到消息后&#xff0c;会直接转发到绑定到它上面的所有队列 Direct Exchange 直连型交换机&#xff0c;根据消息携带的路由键将消息投递…

日语学习-日语知识点小记-进阶-JLPT-真题训练-N2阶段(4):2022年12月2023年12月

日语学习-日语知识点小记-进阶-JLPT-真题训练-N2阶段&#xff08;4&#xff09;&#xff1a;2022年12月&2023年12月 1、前言&#xff08;1&#xff09;情况说明&#xff08;2&#xff09;工程师的信仰&#xff08;3&#xff09;真题训练 2、2个卷的单词部分1、 真题-2023年…

从代码学习深度强化学习 - Actor-Critic 算法 PyTorch版

文章目录 前言算法原理1. 从策略梯度到Actor-Critic2. Actor 和 Critic 的角色3. Critic 的学习方式:时序差分 (TD)4. Actor 的学习方式:策略梯度5. 算法流程代码实现1. 环境与工具函数2. 构建Actor-Critic智能体3. 组织训练流程4. 主程序:启动训练5. 实验结果总结前言 在深…