初识C++(下):const引用/inline/nullptr

news2024/11/26 0:51:50

1.引用

1.1const引用

可以引用一个const对象,但是必须用const引用。const引用也可以引用普通对象,因为对象的访问权限在引用过程中可以缩小,但是不能被放大

#include<iostream>

using namespace std;


int main()
{
	const int a = 10;

	//权限放大是不被允许的
	//int& b = a;

	const int& b = a;

	cout << b << endl;

	//权限缩小是被允许的
	int x = 20;
	const int& c = x;
	cout << c << endl;
	return 0;
}

需要注意是类似 :int& xx = x * 3;    double ret = 2.2; int& aa = ret;这样的场景下x*3的结果会保存在一个临时对象中,int& aa = ret;也类似,在类型转换中会产生临时对象存储中间值,也就是说xx和aa都是引用的;临时对象,而C++的临时对象具有常性,所以这里触发了权限放大,我们必须用常引用才行。

#include<iostream>

using namespace std;


int main()
{
	const int a = 10;

	//权限放大是不被允许的
	//int& b = a;

	const int& b = a;

	cout << b << endl;

	//权限缩小是被允许的
	int x = 20;
	const int& c = x;
	cout << c << endl;

	//x*3会产生一个临时变量这个变量一般为const修饰
	//这样起别名是错的
	//int& xx = x * 3;


	//正确方法
	const int& xx = x * 3;
	cout << xx << endl;

	//发生类型转时取别名也需要加个const
	//因为在类型转换的时候也会产生一个临时变量
	double ret = 2.2;
	const int& aa = ret;
	cout << aa << endl;


	return 0;
}

所谓临时对象就是编译器需要一个空间暂存表达式的求值结果时临时创建的一个未命名的对象,C++中把这个未命名对象叫做临时对象。

2.指针和引用的关系

C++中指针和引用就像两个性格迥异的亲兄弟,指针是哥哥,引用是弟弟,在实践中他们相辅相成,不存在谁代替谁,功能有重叠性,但是各自都有自己的优点。

1.语法概念上引用是一个变量的取别名不开辟空间,指针是存储一个变量的地址,要开空间。

 引用在定义时必须初始化,指针是建议初始化,语法上不是必须的。

引用在初始化引用一个对象后,就不能再引用其他对象了,但是指针可以不断改变所指向的对象。 引用可以直接访问对象,指针需要解引用才能访问指向的对象。

sizeof中含义不同,引用结果为引用类型的大小,但是指针始终是地址空间所占字节个数(32为平台下占4个字节,64位平台下占8字节)。

指针很容易出现野指针和空指针的情况,引用却很少出现,引用使用起来更安全。

2.inline

1.用inline修饰的函数叫做内联函数,编译时C++编译器会在调用的地方展开内联函数,这样调用内联函数就不需要建立函数栈帧了,提高程序效率。 

我们转到汇编发现这个函数没有调用函数栈帧(有call和add语句就是没有展开,没有就是展开了).

2.inline对于编译器来说只是一个建议,真正决定展开或者不展开函数,需要编译器自己决定,也就是说尽管有时候你加了inline编译器也不会展开,C++标准没有准确的一个规定。inline只适用于短小函数。

3.c语言宏函数也会在预处理的时候展开,但是宏函数实现很复杂很容易出错,而且不方便调试。c++设计inline目的就是为了替代宏函数。也就是说内联函数有宏函数的执行效率,又可以像函数那样方便调试。

#include<iostream>
//宏实现常见问题
//#define ADD(a,b) return a+b;
//#define ADD(a,b) a+b;
//#define ADD(a,b) (a+b)

//正确的宏实现
#define Add(a,b) ((a)+(b))
using namespace std;

int main()
{
	int a = 10;
	int b = 20;
	//取别名
	int& ra = a;
	int ret= Add(10, 20);
	cout << ret  << endl;
	return 0;
}

4.inline不建议声明和定义放在两个文件,分离会导致链接错误。因为inline被展开,就没有函数地址,链接时会报错。

3.nullptr

1.NULL实际上是一个宏,在传统的c头文件(stddef.h),可以看到 :

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

2.C++中NULL可能被定义为字面常量0,或者C中被定义为无类型指针(void*)的常量。不论采取何种定义,在使用空值的指针时,都不可避免会遇到一些麻烦,本想通过f(NULL)调用指针版本的f(int*)函数,但是由于NULL被定义为0,调用成了f(int x),因此与程序的初衷违背。f((void*)NULL);调用时会报错。

3.C++11中引入nullptr,nullptr是一个特殊的的关键字,nullptr是一种特殊类型的子面量,它可以转换成任意类型其他类型的指针类型。使用nullptr定义空指针可以避免类型转换的问题,因为nullptr只能被隐式转换为指针类型,而不能转换为整型。

#include<iostream>
using namespace std;

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

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


int main()
{
	//本想通过f(NULL)调用指针版本的f(int*)函数,但是由于NULL被定义为0,调用成了f(int x),因此与程序的初衷违背
	f(0);
	f(NULL);
	
	//f((void*)NULL);

	f(nullptr);

	return 0;
}

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

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

相关文章

SpringBoot中整合RabbitMQ(测试+部署上线 最完整)

一、RabbitMQ安装 由于在测试环境中&#xff0c;我们现在虚拟机上基于docker安装mq docker run \-e RABBITMQ_DEFAULT_USERquick \-e RABBITMQ_DEFAULT_PASS123 \-v mq-plugins:/plugins \--name mq \--hostname mq \-p 15672:15672 \-p 5672:5672 \--network your-net\-d \r…

学习文本到语音转换技术时为何要掌握Mel频谱图?

理解Mel频谱图 “Mel”指的是梅尔频率刻度&#xff08;Mel Frequency Scale&#xff09;&#xff0c;这是一种基于人类听觉感知方式的频率刻度。梅尔频率刻度旨在更好地模拟人耳对声音的感知&#xff0c;因为人类对频率的感知并不是线性的&#xff0c;而是对低频更敏感&#x…

gitlab查看root密码

gitlab查看root密码 gitlab安装后会创建默认的root密码&#xff0c;密码存在配置文件cat /etc/gitlab/initial_root_password中。

深度解析Edge SCDN与CDN:安全加速,全面防护

在现代互联网应用中&#xff0c;CDN已成为提高网站和应用性能不可或缺的技术之一。然而&#xff0c;随着网络安全威胁的日益严峻&#xff0c;单纯依靠CDN提供的加速服务已经不足以满足企业的安全需求。因此&#xff0c;Edge SCDN出现了&#xff0c;它不仅具备CDN的加速特性&…

Selenium + Python 自动化测试12(unittest组织更多用例)

我们的目标是&#xff1a;按照这一套资料学习下来&#xff0c;大家可以独立完成自动化测试的任务。 上一篇我们讨论了unittest中test suite 的构建&#xff0c;可以测试多条测试用例。 本篇文章我们接着讲。使用discover()方法构建更多的测试用例。 1、引入需要完成的任务 上…

【鸿蒙教程】快速集成鸿蒙 IM SDK 并实现单聊发送消息

本文手把手教您快速集成鸿蒙版环信即时通讯 IM 并实现单聊。 教程目录 前提条件准备开发环境SDK导入及声明SDK 初始化注册监听回调注册登录发送消息 前提条件 DevEco Studio NEXT Developer Beta1&#xff08;5.0.3.300&#xff09;及以上&#xff1b;HarmonyOS SDK API 12…

4款视频剪辑免费软件推荐,剪辑必备的神器!

对于许多新入门的剪辑小白或者经费有限的剪辑朋友来说&#xff0c;寻找一款免费且好用的剪辑软件是非常重要的。今天&#xff0c;我就来给大家分享4款很实用且专业的免费剪辑软件。 1、福昕免费剪辑 直达链接&#xff1a;www.pdf365.cn/foxit-clip/ 第一个是款功能全面且易上…

支持海思3520D平台网络硬盘录像机NVR源码与NVR解决方案

支持海思3520D平台网络硬盘录像机NVR源码与NVR解决方案 本NVR模组基于HiSilicon&#xff08;海思&#xff09;平台&#xff0c;提供了一套完整的网络视频录像机&#xff08;NVR&#xff09;解决方案。该方案集成了视频接入、存储、回放、智能处理、告警及系统管理等功能模块&a…

数字化转型的权威指南:《数字化时代的敏捷架构》

「链接」https://shop.architectszone.org.cn/p/t_pc/goods_pc_detail/goods_detail/v_66bc7093e4b0d84dab16b12c 《数字化时代的敏捷架构》培训课程 全球最具影响力数字化转型架构出品方The Open Group 专注于企业架构师职业发展的平台AZone联合推出 The Open Group&#x…

第一百九十七节 Java集合教程 - Java集合Map映射

Java集合教程 - Java映射 映射表示包含的集合键值映射。 Map是一个集合&#xff0c;其中每个元素表示一个键值对作为<key&#xff0c;value> ;.<key&#xff0c;value> 对也称为映射中的条目。键和值必须是引用类型。 映射由 Map<K&#xff0c;V> 接口的实…

笔记:在WPF中如何注册控件级全局事件和应用程序级全局事件

一、目的&#xff1a;在WPF中如何注册控件级全局事件和应用程序级全局事件 二、实现 应用程序级全局事件 //注册应用程序级全局事件 EventManager.RegisterClassHandler(typeof(Button), Button.ClickEvent, new RoutedEventHandler(ic_event_Click)); 如上代码既会注册全局…

[爬虫基础]--抓取豆瓣top250电影, 简单易懂, 零基础入门

1. 抓取目标: 下载top250电影的图片, 并以电影名称作为文件名进行保存 2. 获取网页源代码: 我们每天看到的浏览器页面, 本质上都是html代码和css代码, 向服务器发出请求后, 服务器会返回一连串的信息, 经过浏览器选然后, 就变成了我们每天看到的界面 可以在网页中通过鼠标右…

Linux系统编程 --- day1

目录 1. 标准IO 2. 基本操作 2.1 fopen 2.2 fgetc 2.3 fputc 2.4 fgtes 2.5 fputs 2.6 fread 2.7 fwrite 3. linux的文件 1. 标准IO &#xff08;1&#xff09;标准io的概念 1975 Dennis r IO库&#xff0c;C语言的标准&#xff0c; IO --- input output I&#xff…

当前人形机器人公司及产品介绍

产品型号属地公司名字Optimus美国特斯拉Figure02美国FigureAIAtlas美国波士顿动力通用人形Apollo美国ApptronikPhoenix加拿大Sanctuary AIRoBee意大利OversonicASIMO日本本田NAO日本软银GR-1上海傅利叶远征A1上海智元XR4上海达闼先行者K1上海开普勒青龙上海国创AstribotS1深圳星…

AIDL使用及原理介绍

一、AIDL使用及理解 介绍参考官方文档&#xff1a;https://developer.android.com/develop/background-work/services/aidl?hlzh-cn 1.1、aidl文件的产物 1.1.1 aidl文件 interface IDownloadIpc {//开始下载DownloadResponse start(in DownloadInfoParcel downloadInfo);…

【数据结构与算法】A*算法——自动寻路

这里写目录标题 一.为什么用A*算法二.A*算法的实现原理三.A*算法的实现1.初始化地图2.格子初始化3.两个列表4.起点到终点的路径5.起点到终点的最佳路径★6.资源的释放 四.完整代码1.Astar.h2.Astar.cpp3.main.cpp4.运行结果 一.为什么用A*算法 上节课我们已经讲了最短路径算法…

【Qt】内置对话框

一.Qt内置对话框 Qt 提供了多种可复⽤的对话框类型&#xff0c;即 Qt 标准对话框。Qt标准对话框全部继承于QDialog类。常⽤标准对话框如下&#xff1a; 二.内置对话框分类 1.消息对话框 QMessageBox 1.1 概念 消息对话框是应⽤程序中最常⽤的界⾯元素。消息对话框主要⽤于为…

SpringBoot集成微信小程序(二)【登录、获取头像昵称及手机号】

一、背景 小程序可以通过微信官方提供的登录能力方便地获取微信提供的用户身份标识&#xff0c;快速建立小程序内的用户体系。 微信小程序官方文档&#xff1a;https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html 二、技术栈 SpringBoot…

RFID在晶圆搬运机中的智能化实践

RFID在晶圆搬运机中的智能化实践 应用背景 在半导体制造行业&#xff0c;晶圆搬运是一个至关重要的环节&#xff0c;它不仅影响生产效率&#xff0c;还直接关系到产品的质量和成本。在如今的多品种少量生产中&#xff0c;要保障生产效率和品质&#xff0c;工序管理至关重要。…

Python环境安装及PIP安装(Mac OS版)

官网 https://www.python.org/downloads/ 安装python python-3.12.1-macos11.pkg下载后&#xff0c;安装一直下一步即可 验证是否安装成功&#xff0c;执行python3命令和pip3命令 配置环境变量 获取python3安装位置并配置在.bash_profile #查看python路径 which python3#…