顶层const和底层const

在C++中,const修饰符用于声明常量,有两种常见的形式:顶层const底层const,它们之间的区别在于它们修饰的对象及其在不同场景中的作用。

1. 顶层const (Top-level const)

顶层const用于修饰变量本身,使其成为常量。这意味着变量的值不能被修改。例如:

const int a = 10;

在这段代码中,a是顶层const,表示a的值不能被改变。

  • 作用:限制变量本身,使其不能被修改。
  • 应用场景:通常用于声明某个变量的值不可改变。

2. 底层const (Low-level const)

底层const则用于修饰指针或引用所指向的对象,使得通过指针或引用不能修改该对象的值。例如:

const int* ptr;

这里,ptr是一个指向int常量的指针,ptr本身可以指向不同的地址,但不能通过ptr修改所指向对象的值。

  • 作用:限制指针或引用指向的对象的可修改性。
  • 应用场景:用于指针或引用,使其无法修改所指向的对象的值。

例子区分顶层const和底层const:

int x = 5;
const int* p1 = &x;    // p1是底层const,不能通过p1修改x的值
int* const p2 = &x;    // p2是顶层const,不能改变p2指向的地址
const int* const p3 = &x; // p3既是顶层const又是底层const,既不能修改p3指向的地址,也不能修改x的值
  • p1是一个指向int常量的指针(底层const),可以改变指针的指向,但不能通过p1修改所指向对象的值。
  • p2是一个常量指针(顶层const),即指针本身是常量,不能改变其指向的地址,但可以通过p2修改指向对象的值。
  • p3同时是顶层和底层const,既不能修改指针的指向,也不能修改指针指向对象的值。

总结:顶层const用于限制变量本身的修改,底层const用于限制通过指针或引用修改所指向的对象。

在这里插入图片描述
我将逐行分析这些代码并解释其中的关键点,帮助你理解顶层const和底层const的作用。

const int a = 10;
int b = a;
  • a是顶层const,表示它是一个常量,值为10,不能被修改。
  • b是一个普通的整数,它的值被初始化为a的值(即10),这在C++中是合法的,因为b不是const类型。
const int *const p = new int(10);
int *p1 = p;  // 错误
int *const p2 = p;  // 错误
const int *p3 = p;
  • p是一个顶层和底层const指针:const int*表示p指向一个const int(底层const),即通过p不能修改其所指向的值;const p(顶层const)表示p本身是一个常量指针,不能修改它指向的地址。
  • p1的类型是int*,试图将const int*类型的p赋值给非const的p1,这是非法的,编译器会报错。因为p1可以修改所指向对象的值,但p不能。
  • p2的类型是int *const,表示p2是一个常量指针,不能改变指向的地址,但可以通过p2修改指向对象的值。由于pconst int*,不能通过p2修改对象的值,因此也是非法的。
  • p3的类型是const int*,与p兼容,因此可以赋值。
int *p4 = &a;  // 错误
  • aconst int,但是p4是一个普通的int*,这意味着通过p4可以修改a的值。这是非法的,因为a是一个常量,不能通过普通指针来修改。
const int &r1 = 20;
int &r2 = a;  // 错误
int &r3 = r1;  // 错误
  • r1是一个对const int的引用,绑定到字面值20上,这是合法的,因为C++允许const引用绑定到字面值或常量表达式。
  • r2是一个普通的引用,试图引用a,但aconst,不能通过非const引用绑定到常量。
  • r3也是一个普通的引用,试图引用r1,但由于r1是const,r3不能通过非const引用绑定到一个const引用上。

结论:

  • 顶层const限制变量本身的修改,如p指向的地址不能被修改。
  • 底层const限制通过指针或引用对对象值的修改,如p指向的值不能被修改。
  • 非const指针或引用不能指向const对象或通过非const引用绑定const对象。

p3的类型是const int*,与p兼容,因此可以赋值。这个如何理解

这句话的意思是:p3的类型是const int*,而p的类型是const int *const。虽然p是一个常量指针(顶层const),但它指向的是一个const int类型的值(底层const),因此p的底层类型与p3相同,都是指向const int的指针。

详细解释:

const int *const p = new int(10);  // p 是 const 指针,指向 const int
const int *p3 = p;                 // p3 是指向 const int 的普通指针
  • p的类型const int *const p

    • const int *:表示指针指向一个const int类型的对象(底层const),即不能通过该指针修改所指向的整数值。
    • const p:表示p本身是一个常量指针(顶层const),也就是说指针的地址不能改变。
  • p3的类型const int *p3

    • const int *:表示指针p3指向一个const int类型的对象(底层const),即不能通过该指针修改所指向的整数值。

为什么p3可以赋值为p

尽管p是一个常量指针(顶层const),但p3不需要关心p本身是否是常量指针,p3只关心p指向的对象类型(底层const)。由于p指向的是一个const int,这与p3的类型兼容,因此可以赋值。

具体来说:

  • p指向的是const int,这与p3的底层const要求兼容。
  • 赋值时,p的顶层const(即指针本身不可修改)并不影响赋值给p3,因为p3本身不是常量指针,允许指针指向其他地址。

因此,p3可以指向与p相同的地址,但不能通过p3修改指向的值(因为是const int*)。

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

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

相关文章

Jenkins 通过 Version Number Plugin 自动生成和管理构建的版本号

步骤 1:安装 Version Number Plugin 登录 Jenkins 的管理界面。进入 “Manage Jenkins” -> “Manage Plugins”。在 “Available” 选项卡中搜索 “Version Number Plugin”。选中并安装插件,完成后可能需要重启 Jenkins。 步骤 2:配置…

SQL进阶技巧:每年在校人数统计 | 区间重叠问题

目录 0 问题分析 1 数据准备 2 问题分析 3 小结 区间重叠问题 0 问题分析 有一个录取学生人数表 in_school_stu,记录的是每年录取学生的人数及录取学生的学制,计算每年在校学生人数。 1 数据准备 create table in_school_stu as ( select stack(5,1,2001,2,1200,2,2000…

Sui Narwhal and Tusk 共识协议笔记

一、Overwiew [ 整体流程: Client提交transaction到Narwhal Mempool。(Narwhal Mempool由一组worker和一个primary组成) Mempool接收到的Transaction->以Certificate的形式进行广播 由worker将交易打包为Batch,worker将Batch的hash发送给primary primary上运行了mempo…

关系代数 | 数据库SQL

文章目录 关系运算符笛卡尔积笛卡尔积应用 运算符符号含义集合运算符并∪交∩差-笛卡尔积专门的关系运算符选择σ投影π连接⋈除 关系运算符 笛卡尔积 集合运算符中,主要对笛卡尔积做解释: 在数学中,两个集合X和Y的笛卡儿积(英语…

ThreadLocal 释放的方式有哪些

ThreadLocal基础概念:IT-BLOG-CN ThreadLocal是Java中用于在同一个线程中存储和隔离变量的一种机制。通常情况下,我们使用ThreadLocal来存储线程独有的变量,并在任务完成后通过remove方法清理这些变量,以防止内存泄漏。然而&…

使用 WebStorm 导入已有的 Vue 项目并运行的步骤与注意事项

目录 1. 引言2. WebStorm 环境准备2.1 安装 WebStorm2.2 配置 Node.js 和 npm2.3 使用 nvm 管理 Node.js 和 npm 版本2.4 npm 版本与 Vue 版本对应关系 3. 导入已有的 Vue 项目3.1 打开 Vue 项目3.2 安装项目依赖3.3 使用 nvm 控制 Node.js 和 npm 版本 4. 运行 Vue 项目4.1 启…

软件工程-图书管理系统的概要设计

软件概要设计说明书 目录 软件概要设计说明书 一、引言 1.1 编写目的 1.2 背景 1.3 定义 1.3.1特定对象 1.3.2专业术语 1.4 参考资料 二、总体设计 2.1 需求规定 2.1.1信息要求 2.1.2功能要求 2.2 运行环境 2.3 基本概要设计和处理流程 2.4 体系结构设计 2.5 模…

从戴尔公司中国大饭店DTF大会,看科技外企如何在中国市场发展

【科技明说 | 科技热点关注】 2024戴尔科技峰会在8月如期举行,虽然因事未能抵达现场参加,我只是观看了网上在线直播,也未能采访到DTF现场重要与会者,但是通过数十年对戴尔的跟踪与观察,我觉得2024戴尔科技…

基于Java+SpringBoot+Vue+MySQL的美容美发管理系统

作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 基于SpringBootVue的美容美发管理系统【附源码文档】、前后…

const、inline、nullptr的使用

目录 1.const引用 1.1权限的放大 1.2权限的缩小 2.inline 3.nullptr 1.const引用 可以引用一个const对象,但是必须用const引用。const引用也可以引用普通对象,因为对象的访问权限在引用过程中可以缩小,但是不能放大。 不需要注意的是类…

uniapp 实现tabbar图标凸起

实现tabbar图标凸起有两种,第一种是自定义tabbar,第二种就是使用官方的tabbar跟api实现,自定义在体验中不如原生的tabbar,所以我下面展示的是使用官方的tabbar跟api实现 效果如图: 左边是未选中中间的凸起&#xff0c…

大模型推理--KV Cache

KV Cache是大模型推理中常用到的一个技巧,可以减少重复计算,加快推理速度。不少人只是从概念上知道它可以减少重复计算,详细的原理则知之甚少,此外为啥只有KV Cache而没有Q Cache呢,我们在本博客中给出详尽的解释。我想…

一些硬件知识(十八)

两个信号PIN之间串接电阻的作用: 1.阻抗匹配 2.吸收反射 3.防止程序异常导致两个IO都是输出的时候短路 尤其针对下图中的信号: 清理穿越机电机中的灰尘,可以用密封胶泥的办法: 一定要小心垫片的掉落: 20块左右的快充充…

游泳馆押金管理+手牌管理+刷手牌 开通方法

一、游泳馆手牌押金管理 1. 减少手牌丢失:收取押金可以让顾客更加谨慎地保管手牌,降低手牌丢失的概率。 2. 保障设施安全:有助于防止顾客对手牌的不当使用或故意破坏,保护游泳馆的设施和资源。 3. 规范顾客行为:促使…

SLM561A​​系列 60V 10mA到50mA线性恒流LED驱动芯片 为智能家居照明注入新活力

SLM561A系列选型参考: SLM561A10ae-7G SOD123 SLM561A15ae-7G SOD123 SLM561A20ae-7G SOD123 SLM561A25ae-7G SOD123 SLM561A30ae-7G SOD123 SLM561A35ae-7G SOD123 SLM561A40ae-7G SOD123 SLM561A45ae-7G SOD123 SLM561A50ae-7G SOD123 …

Pr下载安装教程2024(Adobe Premiere 2024)最新版分享百度网盘链接地址

提示:主要讲述了软件安装及初步使用流程。Pr下载安装教程2024最新版分享百度网盘链接地址首先,解压文件夹后,双击安装包进行安装,选择简体中文并确认安装位置,可按需更改。随后,点击继续等待安装完成并启动…

jmeter依赖jar包找不到类路径

这两天我在纠结这个问题,为啥我maven打包放在jmeter路径下后,jmeter的bean Shell 就是找不到这个类。 纠结很久解开了。我记录下,留给后来的朋友。 Error invoking bsh method: eval Sourced file: inline evaluation of: import org.apache…

python、C++、rust速度比较

TIobe指数依据向主要搜索引擎提交编程语言名称时返回的网页数量来衡量编程语言的流行程度。该指数每月更新一次,并提供了自2002年以来的历史数据。 其官网是https://www.tiobe.com/tiobe-index/ 有意思的事情来了,看下图。 这是编程语言排名的tiobe网站…

两数之和--力扣1

两数之和 题目思路C代码 题目 思路 根据题目要求,元素不能重复且不需要排序,我们这里使用哈希表unordered_map。注意题目说了只对应一种答案。 所以我们在循环中,使用目标值减去当前循环的nums[i],得到差值,如果我们…

LabVIEW如何确保采集卡稳定运行

在LabVIEW开发中,如何确保硬件采集卡稳定运行,特别是长期采集电压信号,是系统稳定性的重要考虑因素。用户在使用采集卡时,可能需要频繁进行开始、停止和重新采集的操作,这对硬件和软件提出了高要求。下面介绍实现长期稳…