【C++掌中宝】C++ 中的空指针救世主——nullptr

news2024/11/14 23:14:45

在这里插入图片描述

文章目录

  • 1. 什么是 NULL?
  • 2. NULL 在 C 和 C++ 中的区别
  • 3. C++11 引入 nullptr 的原因
  • 4. nullptr 与 NULL 的区别
  • 5. nullptr 的应用场景
  • 6. 模拟 nullptr 的实现
  • 7. 总结
  • 结语

1. 什么是 NULL?

在 C 和 C++ 编程中,NULL 常用于表示空指针,但它本质上是一个宏定义

  • 在C语言中,NULL 通常被定义为 (void *)0,也就是一个指向空的 void 指针。
  • 但在 C++ 中,NULL 常常被定义为整数常量 0

在传统的C头文件(stddef.h)中,可以看到如下代码:

#ifndef NULL
	#ifdef __cplusplus
		#define NULL 0
	#else
		#define NULL ((void *)0)
	#endif
#endif

由于在 C++ 中,void* 不能隐式转换为其他类型的指针,因此将 NULL 定义为 0。这导致在函数重载时可能会出现二义性问题

2. NULL 在 C 和 C++ 中的区别

在 C 语言中,NULL 定义为 (void *)0,它可以隐式转换为任何类型的指针。这使得以下代码在 C 中可以正常编译和运行:

int *pi = NULL;
char *pc = NULL;

然而,在 C++ 中,由于更严格的类型检查,void* 不能隐式转换为其他指针类型。因此,C++ 中的 NULL 通常被定义为整数常量 0。这导致了以下代码在 C++ 中的编译错误

int *pi = (void*)0;  // OK in C, error in C++

报错如下

在这里插入图片描述


除此之外,NULL 在函数重载时也会导致意外行为。例如,考虑以下代码:

#include<iostream>
using namespace std;
void f(int x)
{
	cout << "f(int x)" << endl;
}
void f(int* ptr)
{
	cout << "f(int* ptr)" << endl;
}
int main()
{
	f(0);
	f(NULL);
} // 这会调用哪个版本的 f()?

运行结果如下
在这里插入图片描述

由于 NULL 被定义为 0,这里会调用 int 参数的版本,而不是我们期望的指针版本,所以最后两个结果都是选择int 参数的版本。

3. C++11 引入 nullptr 的原因

为了消除 NULL 在 C++ 中的二义性问题,C++11 引入了 nullptr 作为一种新型空指针常量nullptr 是一个关键字,代表一种特殊类型,使用nullptr定义空指针可以避免类型转换的问题,因为它只能转换为任意指针类型,但不能转换为整数类型

例如,以下代码可以正确运行并调用我们期望的函数版本:

#include<iostream>
using namespace std;

void f(int x) {
    cout << "foo(int x)" << endl;
}

void f(int* ptr) {
    cout << "foo(int* ptr)" << endl;
}

int main() {
    f(nullptr);  // 调用 f(int* ptr)
    return 0;
}

nullptr 的引入解决了函数重载中的二义性问题,确保空指针总是正确地匹配到指针类型的重载函数。

4. nullptr 与 NULL 的区别

虽然 NULL 仍然可以在 C++ 中使用,但它在特定场景下会引发错误或误解。相比之下,nullptr 是一种更加安全且明确的选择:

  • 在C++中NULL 通常是整数 0,会引发二义性问题。
  • nullptr 是一个指针常量,可以隐式转换为任意指针类型,不会引发二义性问题。

例如:

void func(int x) {
    cout << "func(int)" << endl;
}

void func(char* p) {
    cout << "func(char*)" << endl;
}

int main() {
    func(0);         // 调用 func(int)
    func(nullptr);   // 调用 func(char*)
    return 0;
}

5. nullptr 的应用场景

在 C++11 及更高版本中,推荐使用 nullptr 代替 NULL 来表示空指针,特别是在函数重载的场景下。例如:

int* p1 = nullptr;
if (p1 == nullptr) {
    cout << "p1 是空指针" << endl;
}

需要注意的是,nullptr 不能赋值给整数类型,因此以下代码会导致编译错误:

int n = nullptr;  // 编译错误

报错如下
在这里插入图片描述

6. 模拟 nullptr 的实现

对于不支持 C++11 的编译器,我们可以自己模拟实现 nullptr。以下是一个简单的实现:

const class nullptr_t {
public:
    template<class T>
    operator T*() const { return 0; }

    template<class C, class T>
    operator T C::*() const { return 0; }

private:
    void operator&() const;
} nullptr = {};

7. 总结

NULL 是一个历史遗留的宏定义,虽然在 C++ 中仍然可以使用,但它会在特定场景下引发意外的行为和错误。为了消除这些问题,C++11 引入了 nullptr,作为一种类型安全的空指针表示。

在现代 C++ 编程中,强烈推荐使用 nullptr 代替 NULL,确保代码在空指针处理上更加明确和安全。

结语

通过本文,读者应当已经掌握了 nullptr 的基本概念、与 NULL 的区别以及如何在实际编程中应用它。如果你还在用 NULL,是时候拥抱 nullptr,让你的代码更加健壮吧!

今天的分享到这里就结束啦!如果觉得文章还不错的话,可以三连支持一下。

也可以点点关注,避免以后找不到我哦!

Crossoads主页还有很多有趣的文章,欢迎小伙伴们前去点评,您的支持就是作者前进的动力!
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

展示中国客车硬实力!苏州金龙海格纯电客车惊艳汉诺威商用车展

德国当地时间2024年9月22日&#xff0c;IAA汉诺威商用车展在德国汉诺威展览中心圆满落幕。本届展会&#xff0c;苏州金龙海格客车携新能源公交明星产品Azure7、斯堪尼亚海格高端巴士Fencer F1 Integral EV纯电车型重磅亮相&#xff0c;获得了众多参会嘉宾的好评和关注。来自欧洲…

【活动】人工智能时代,程序员如何保持核心竞争力?需要掌握哪些技能?

人工智能时代&#xff0c;程序员如何保持核心竞争力&#xff1f; 随着人工智能&#xff08;AI&#xff09;技术的迅猛发展&#xff0c;程序员面临着前所未有的挑战和机遇。AI不仅改变了软件开发的方式&#xff0c;也重新定义了程序员的角色。在这种背景下&#xff0c;如何保持…

人工智能助力阿尔茨海默症治疗:微软与上海精神卫生中心的新研究

最近&#xff0c;微软研究院与上海市精神卫生中心合作&#xff0c;基于微软 Azure OpenAI 服务中的多模态大模型&#xff0c;开发了一种名为“忆我”&#xff08;ReMe&#xff09;的个性化认知训练框架。这一创新项目旨在通过数字化手段扩展自动化认知训练的范围&#xff0c;为…

2025考研,报名和初试时间定了!

2025年全国硕士研究生招生初试时间为2024年12月21日至22日&#xff0c;考试时长为6小时的考试科目在12月23日举行。 请考生届时登录“中国研究生招生信息网”&#xff08;网址&#xff1a;https://yz.chsi.com.cn&#xff09;参加报名&#xff0c;查看报名须知、招生单位招生章…

软考高级:云计算架构的五层 AI 解读

云计算架构通常由多个层次构成&#xff0c;每个层次负责不同的功能&#xff0c;协同工作来提供完整的云服务。下面我将详细解释云计算架构的五个主要层次&#xff1a;管理层、用户访问层、应用层、平台层和资源层。 生活化例子 想象一下&#xff0c;云计算架构就像是一座大型…

从金蝶云星空到管易云通过接口配置打通数据

从金蝶云星空到管易云通过接口配置打通数据 接通系统&#xff1a;金蝶云星空 金蝶K/3Cloud结合当今先进管理理论和数十万家国内客户最佳应用实践&#xff0c;面向事业部制、多地点、多工厂等运营协同与管控型企业及集团公司&#xff0c;提供一个通用的ERP服务平台。K/3Cloud支持…

yolov8环境安装

yolov8 git地址 https://github.com/ultralytics/ultralytics/tree/main 我的电脑显卡配置 nvidia-smi cuda11.8下载 https://developer.nvidia.com/cuda-11-8-0-download-archive?target_osWindows&target_archx86_64&target_version10&target_typeexe_local …

保姆级教程!0基础小白也适用,教你用AI美女在小红书“疯狂上分”

文章开始之前&#xff0c;先考考各位小伙伴的眼力&#xff1a;下面的图是真人还是 AI&#xff0c;你能分辨出来吗&#xff1f; 答案是&#xff1a;AI&#xff0c;AI&#xff0c;全是使用stable diffusion生成的AI美女&#xff01; 说实话&#xff0c;最近AI美女是彻底杀疯了&a…

大数据Hive组件安装

组件版本 组件版本Hadoop3.3.0JDK1.8.0_241Mysql5.7.25Hive3.1.2 Hadoop集群服务分布 Node1Node2Node3NameNode DataNode DataNodeDataNode NodeManager NodeManagerResourceManagerSecondaryNameNode 安装前请确定Hadoop集群服务全部启动&#xff0c;不然后续测试时会报…

【学习笔记】手写 Tomcat 四

目录 一、Read 方法返回 -1 的问题 二、JDBC 优化 1. 创建配置文件 2. 创建工具类 3. 简化 JDBC 的步骤 三、修改密码 优化返回数据 创建修改密码的页面 注意 测试 四、优化响应动态资源 1. 创建 LoginServlet 类 2. 把登录功能的代码放到 LoginServlet 类 3. 创…

企业新购买的设备需要做仪器校准吗?为什么新设备也要做检测?

企业在定制一批设备仪器到厂后&#xff0c;会需要对设备进行验货和接收&#xff0c;而这个环节很多人对于设备是否同时需要先做校准的问题犹豫不决&#xff0c;一些企业觉得新设备都是刚买的&#xff0c;做仪器校准没有必要&#xff0c;但是另一部分认为即便是新买的仪器也要先…

easyexcel常见问题分析

文章目录 一、读取数字多了很多小数位的精度问题 一、读取数字多了很多小数位的精度问题 浮点型转成BigDecimal的时候会出现精度问题&#xff0c;例如 这儿设置的实体类对象类型是String&#xff0c;默认用到的是StringNumberConverter转换器 2.1.4 版本 public class Strin…

葡萄城亮相2024全球产品经理大会,共探创新之旅

葡萄城亮相2024全球产品经理大会&#xff0c;共探创新之旅 9 月 20-21 日&#xff0c;由 CSDN 举办的“2024 全球产品经理大会”于北京盛大开幕&#xff0c;现场超 40 位互联网与科技产品领域专业人士发表主题演讲&#xff0c;1000 与会者齐聚一堂。 大会现场气氛热烈&#…

【LangChain系列】实战案例5:用LangChain实现灵活的Agents+RAG,该查时查,不该查时就别查

目前为止&#xff0c;我们实现的RAG练习中&#xff0c;答案都是全部来源于检索到的文本内容。而检索过程可能在某些情况下是不需要的。 如何优化这个过程&#xff0c;让我们的RAG程序在必要时才去检索&#xff0c;不必要时&#xff0c;直接使用大模型原有数据来回答呢&#xf…

Python酷玩之旅_如何在Centos8顺利安装Python最新版(3.12)

全文导览 前言Q&#xff1a;如何在Centos8顺利安装Python最新版一. 下载安装包1.1 wget1.2. 官网下载 二. 执行安装2.1. 检查环境2.2. 安装依赖2.3. 解压tgz包2.4. 编译2.5. 安装2.6. 设置环境变量2.6.1 编辑/etc/profile2.6.2 激活生效 三. 操作示例3.1. helloworld 结语 前言…

DevOps学习路线图

DevOps 是软件工程领域中的一种文化和实践方法&#xff0c;它将开发 (Dev) 和运维 (Ops) 相结合&#xff0c;从而在应用程序规划、开发、交付和运营中统一人员、流程和技术。 DevOps 支持以前孤立角色&#xff08;如开发、IT 运营、质量工程和安全&#xff09;之间的协调和协作…

【Elasticsearch】-实现图片向量相似检索

1、http请求方式 如果elasticsearch服务设置账号密码&#xff0c;则在请求的header中添加 Basic Auth 认证 请求方式&#xff1a;Post 请求地址&#xff1a;/index_name/_search 请求body&#xff1a;json格式 {"size": 10, //返回条数"min_score": 0.…

【10000字pandas数据可视化超全笔记整理】Numpy Pandas | 常用API介绍 | 缺失值处理 matplotlib数据可视化介绍

文章目录 Numpy 部分NumPy的数组类被称作ndarray&#xff0c;通常被称作数组。属性创建方法内置函数运算基本运算矩阵运算 Pandas部分总述Serise 对象创建属性方法运算 DataFrame属性索引操作添加删除插入列 保存读取文件保存读取 数据加载分组聚合语法格式: 基本绘图 数据组合…

【设计模式-迭代】

定义 迭代器模式&#xff08;Iterator Pattern&#xff09;是一种行为型设计模式&#xff0c;用于提供一种顺序访问集合对象元素的方式&#xff0c;而不暴露该对象的内部表示。通过迭代器&#xff0c;客户端可以在不需要了解集合实现的细节的情况下遍历集合中的元素。 UML图 …

Hi.Events —— 您的全方位活动管理与票务平台

大家好&#xff01;今天给大家介绍一个超厉害的开源项目&#xff1a;Hi.Events&#xff0c;这是一个功能丰富的自托管活动管理和票务平台&#xff0c;无论是会议还是俱乐部活动&#xff0c;它都能帮你轻松搞定&#xff01; 项目介绍 Hi.Events是一款功能丰富、自托管的开源活动…