【C++11】nullptr关键字使用详解

系列文章目录

C++11新特性使用详解-持续更新
https://blog.csdn.net/xiaofeizai1116/category_12498334.html


文章目录

    • 系列文章目录
    • 一、简介
    • 二、引入nullptr原因
      • 1. 消除歧义
      • 2. 兼容性问题
      • 3. 类型安全
    • 三、使用场景
      • 1. 初始化指针变量
      • 2. 判断指针是否为空
      • 3. 释放内存后置为空
    • 四、总结


一、简介

C++11引入了nullptr关键字,它是一种空指针类型,用于表示空指针。

二、引入nullptr原因

C++11之前空指针一般用`NULL宏或者0值表示,为什么还有引入nullptr呢?

1. 消除歧义

NULL宏在不同的编译器环境中可能代表不同的值,容易造成对空指针的理解混乱;另外把0赋给指针,也容易给人造成把整数常量赋给指针的误解。使用nullptr从语言层面解决了上述问题,提高了代码的可读性。

Note
NULL本质上是0,在内存中表示不存在或没有指向任何对象的指针。如果一个指针被初始化为NULL,意味着它目前不指向任何对象或数据。

2. 兼容性问题

不同平台对NULL的定义不同,可能导致移植问题。相比之下,因为nullptr是语言层面的关键字,不会存在平台依赖性问题,从而提高代码的可移植性。

3. 类型安全

nullptr是一个类型安全的空指针,它明确地表示一个空指针,不能转换成任何除void*以外的其他类型。避免了使用NULL时可能出现的类型转换问题。

Note
NULL是一个宏,不是关键字,所以它不会被编译器检查类型。如果将其用于需要指针类型的地方,编译器会将其视为0,而不是一个指针类型。

/*
下面这段代码会运行时会崩溃,原因如下
NULL是一个宏,通常被定义为0或((void*)0),表示一个空指针。当我们将一个指针变量赋值为NULL时,它表示这个指针变量不指向任何有效的内存地址。
在解引用一个指针时,我们需要将指针所指向的内存地址中的值读取出来。在代码int x = *p1中,表示读取p1所指向的内存地址中的值。由于p1是一个int类型的指针,编译器期望p1指向一个整数类型的内存地址。但是,由于NULL是一个void*类型的值,它不是一个整数类型的值,当试图将一个void类型的值赋给一个int类型的变量时,因为类型不匹配,编译器会报错。
*/
int* p1 = NULL;
int x = *p1;
/*
相比之下,使用nullptr可以避免类型不匹配的问题。
nullptr是一个类型安全的空指针,它明确地表示一个空指针。
编译器会检查使用nullptr的上下文,确保它被正确地用于指针类型。在这段代码中,p2被初始化为nullptr,表示它是一个空指针。
由于p2被声明为int*类型,编译器期望p2指向一个整数。然而,由于p2是空的,不能解引用它来获取一个整数值。编译器会报错,避免了类型转换问题。
*/
int* p2 = nullptr;
int x = *p2; // 编译器会报错,因为p是一个空指针

三、使用场景

1. 初始化指针变量

用nullptr声明一个空指针变量

int* p = nullptr;  // 初始化一个整型指针变量p,值为空指针

在需要指针类型的地方,编译器会根据上下文自动将nullptr转换为正确的指针类型

/*
在这个例子中,我们调用func函数时传递了一个空指针作为参数。编译器会自动将nullptr转换为整数类型的指针,并传递给func函数。
func函数在接收到空指针后,就可以避免对无效的内存地址进行操作,从而避免了潜在的错误。
*/
void func(int* p) {  // ...  
}  int main() {  func(nullptr); // 使用nullptr表示不传递任何有效的指针  return 0;  
}

2. 判断指针是否为空

int* p = getPointFunc();  
if (p != nullptr) {  // 如果p不为空指针,则执行这里的代码  
}

3. 释放内存后置为空

int* p = new int;  // 动态分配内存  
// 使用p指向的内存  
delete p;  // 释放内存  
p = nullptr;  // 明确地将p设置为空指针

四、总结

总的来说,nullptr是以一种更安全、更清晰的方式来处理空指针。只要正确理解和合理使用,它就能够帮助我们编写出质量更高、更容易维护的代码。

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

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

相关文章

【nlp】3.5 Transformer论文复现:3.解码器部分(解码器层)和4.输出部分(线性层、softmax层)

Transformer论文复现:3.解码器部分(解码器层)和4.输出部分(线性层、softmax层) 3.1 解码器介绍3.2 解码器层3.2.1 解码器层的作用3.2.2 解码器层的代码实现3.2.3 解码器层总结3.3 解码器3.3.1 解码器的作用3.3.2 解码器的代码实现3.3.3 解码器总结4.1 输出部分介绍4.2 线性…

Python---函数定义时缺省参数(参数默认值)

缺省参数也叫默认参数,用于定义函数,为参数提供默认值,调用函数时可不传该默认参数的值(注意:所有位置参数必须出现在默认参数前,包括函数定义和调用)。 def user_info(name, age, gender男):pr…

Elaticsearch学习

Elaticsearch 索引 1、索引创建 PUT /index_v1 {"settings": {"number_of_shards": 3,"number_of_replicas": 1},"mappings": {"properties": {"aaa": {"type": "keyword","store&qu…

汇编-CALL和RET指令

CALL指令调用一个过程, 使处理器从新的内存位置开始执行。过程使用RET(从过程返回) 指令将处理器转回到该过程被调用的程序点上。 CALL指令的动作: 1.将CALL指令的下一条指令地址压栈(作为子过程返回的地址) 2.将被调过程的地址复制到指令指针寄存器E…

搜维尔科技:Faceware面部捕捉最佳实践!

视频源和分辨率: 我们的软件针对 RGB 彩色素材进行了优化,不支持使用红外摄像机。 我们建议视频分辨率为 720p 和 1080p。低于 720p 的分辨率可能会对跟踪质量产生负面影响,而高于 1080p 的分辨率会导致存储要求和传输时间增加,而…

python——第十三天

uuid 是通用唯一识别码(Universally Unique identifier)的缩写 UUID是一个128比特的数值 uuid模块: 获取一个128位(比特)的永不重复的数字,当然我们使用的时候会转换为32个的字符串 impor uuud uui…

【Java 进阶篇】Jedis:让Java与Redis轻松对话的利器

在现代软件开发中,缓存系统是提高系统性能的常见手段之一,而Redis作为一个高性能的缓存数据库,被广泛应用于各类系统。如果你是Java开发者,那么使用Jedis库可以让你轻松地与Redis进行交互。本文将带你深入了解Jedis的快速入门&…

c语言-冒泡排序

冒泡排序原理: 冒泡排序是一种简单直观的排序算法,它重复地遍历待排序的元素序列,比较相邻的两个元素,如果它们的顺序不符合要求(例如升序要求前面的元素小于后面的元素),则交换它们的位置。遍历…

国家开放大学平时作业 练习题

试卷代号:1377 理工英语3 参考试题 一、交际用语(共计10分,每小题2分) 1-5题:选择正确的语句完成下列对话,并将答案序号写在答题纸上。 1.-1 won the first prize in todays speech contest. - …

R语言——图解taxize,强烈推荐收藏关注,持续更新中

图解taxize 1. taxize分解思路1.1 图解说明 2. 针对不同数据库的函数组2.1 APGⅢ2.2 BOLD(barcode of life data system) 1. taxize分解思路 taxize可以帮助人们从许多数据库中获取信息。 由于要处理的数据库很多,导致taxize包含的功能函数…

基本锁介绍

锁 1、分类 乐观锁:在select的时候不会加锁,是基于程序实现的,所以不会存在死锁的情况。适用于读多写少的场景(写的并发量相对不高),可以提高系统的吞吐量。因为如果写多的话,乐观锁会有很大机率更新失败…

可持续创新 精选路线

在加速企业数字化转型、 实现智能制造的升级之路上! 使用好的工具固然重要, 而有好工具,也要会用工具。生信科技不仅为企业提供强大的产品支持, 更有全方位的定制化服务, 提升工程师的工具应用能力, 让企业…

C++ Qt QFile用法介绍与代码演示

作者:令狐掌门 技术交流QQ群:675120140 csdn博客:https://mingshiqiang.blog.csdn.net/ 文章目录 打开和关闭文件读取文件写入文件示例代码自定义格式文件解析在Qt 中 QFile 的类用于读写本地文件系统中的文件。它继承自 QIODevice,所以它包含了许多用于数据输入和输出的功…

c++ 课程笔记

105课: cpp文件分为 .h .cpp .cpp 文件 110课:124课 深拷贝 浅拷贝 自建拷贝构造解决浅拷贝释放new后堆区析构函数的问题 (浅拷贝 拷贝内存地址, 释放堆区时 导致源数据 释放时,该地址无数据?而报错) 浅拷贝: 拷贝了对方的值和 堆区内存地址(删除 影响原数据堆区) 深拷贝…

第二类曲线积分@对坐标的曲线积分

文章目录 abstract对坐标的曲线积分变力沿曲线所做的功平均功(恒力做功)变力做工弧段微分第二类曲线积分的定义函数在曲线弧上连续推广:空间曲线弧的第二类曲线积分常用形式和简写利用第二类曲线积分表示变力做功性质 计算方法证明对坐标 x x x对坐标 y y y相加积分限和曲线弧起…

文件批量重命名技巧:图片文件名太长怎么办?告别手动改名方法

在日常生活中,常常会遇到文件名过长导致的问题。尤其是在处理大量图片文件时,过长的文件名可能会使得文件管理变得混乱不堪。现在来看下云炫文件管理器如何批量重命名,让图片文件名变得更简洁,提高工作效率。 操作1、在云炫文件…

python运算符重载之字符串显示和右侧加法

1 python运算符重载之字符串显示和右侧加法 1.1 重载字符串显示 1.1.1 str和repr python调用prin()t时,自动调用__str__和__repr__, python调用str()时,自动调用__str__和__repr__, python调用repr()时,自动调用_…

深入理解C语言指针基础概念:定义、内存地址与声明初始化

导言: 在C语言中,指针是一项强大而重要的概念,直接涉及内存的底层操作。理解指针的基础概念对于熟练运用C语言以及理解底层系统工作原理至关重要。本文将深入研究指针的定义、内存地址的概念以及指针的声明和初始化,帮助读者建立对…

C++之unordered_map/set的使用

前面我们已经学习了STL中底层为红黑树结构的一系列关联式容器——set/multiset 和 map/multimap(C98). unordered系列关联式容器 在C98中, STL提供了底层为红黑树结构的一系列关联式容器, 在查询时效率可达到log2N,即最差情况下需要比较红黑树的高度次, 当树中的节点非常多时,…

3 动态规划解解码问题

来源:LeetCode第91题 难度:中等 描述:一条包含字母A-Z的消息通过以下映射进行了编码: A->1,B->2,z->26,要接吗已编码的消息,所有数字必须基于上述映射的方法,反向映射回字母(可能由多种方法),例…