当前位置: 首页 > news >正文

深入了解C++中const的用法

文章目录

    • 一、C++中的const如何理解?
    • 二、C++中的const与C语言中的const有何区别?
    • 三、const与指针、引用的结合使用

一、C++中的const如何理解?

在C++中,const是一个关键字,用来表示常量性,意在告诉编译器某些变量或对象的值是不可修改的,从而提高代码的安全性和可读性。

二、C++中的const与C语言中的const有何区别?

1. 语义层面的不同

在C语言中,const更多地是一个承诺,它表示变量在当前作用域中不能被修改,但这种约束不是绝对的,可以通过特定的方式绕过,例如强制类型转换。
在C++中,const语义更加严格和完善。它不仅约束变量,还能作用于成员函数、引用、指针等,且配合C++的类型系统,实现了更强的编译时检查。

2. const与引用

在C语言中没有引用的概念,因此const无法结合引用使用。
C++支持常量引用,用来避免拷贝,提高效率,同时保护原始数据不被修改。

void func(const int& ref) {// ref 是只读的,不能修改原始值
}

这种用法在C++中非常常见,特别是在传递大型对象时。

3. 修饰函数

C语言没有成员函数的概念,因此const无法作用于函数级别。
C++允许const修饰成员函数,表示该函数不会修改对象的状态。这种语义在面向对象编程中非常重要。

class MyClass {
public:void display() const { /* 不会修改成员变量 */ }
};

4.绕过const的方式
C语言可以通过强制类型转换((int*))来绕过const的限制。在C语言中const修饰的变量,可以不用初始化,它不叫常量,而是叫常变量。

const int a = 20;
int *p = (int*)&a;
*p = 30;
printf("%d %d %d\n", a, *p, *(&a));

输出结果:30 30 30

虽然C++也支持强制类型转换,但C++提供了更安全的const_cast,明确表示是移除const限定符。

const int a = 10;
int* p = const_cast<int*>(&a);
*p = 20; // 合法,但可能导致未定义行为

5.编译方式不同

在C语言中const就是被当作一个变量来编译生成指令的。
在C++中,所有出现const常量名字的地方,在编译时都被常量的初始化值替换了。且不能作为左值。

在C++中const用字面常量去初始化,如:

int main() {const int a = 20;//a是使用立即数进行的初始化,所以a为常量int array[a] = {};int* p = (int*)&a;*p = 30;std::cout << a << "," << *p << std::endl;return 0;
}

输出结果:20,30

在C++中const用变量去初始化,如:

int main() {int b = 20;const int a = b;//a的初始值不是立即数,是一个变量,所以a此时为常变量//int array[a] = {}; //无法使用变量初始化数组int* p = (int*)&a;*p = 30;std::cout << a << "," << *p << std::endl;return 0;
}

输出结果:30,30

三、const与指针、引用的结合使用

const修饰的变量常出现的错误是:

常量不能作为左值(不能直接修改常量的值)。
不能把常量的地址泄露给一个普通指针或者普通的引用变量(不能间接修改常量的值)。

int main() {const int a = 10;int b = 20;a = b; //错误:常量a不能再作为左值,表达式必须是可修改的左值int* p = &a; //错误: 不能将const int* 转换为int*,这样就会间接修改a的值return 0;
}

1.const和一级指针的结合
注意:const修饰的是离它最近的类型

const int *p:const离int最近,所以修饰的是int类型,而const修饰的表达式是*p,这个时候就不能再修改*p的值,即指针的指向不能再做修改(指针的指向是常量),但是指针的本身是可以被修改的,比如p = &b。换句话说就是p可以指向不同的int类型的内存,但是不能通过指针间接修改指向的内存的值。
int const *p:const离int最近,修饰的是int类型,所以const修饰的表达式是*p,作用同上。
int *const p:const离int*最近,修饰的是int*类型,所以const修饰的是p本身。即这个指针的本身是常量,所以一旦p初始化指向某块内存,那么就不能再更改它的指向。但是可以通过指针解引用修改指向的内存的值。
const int *const p:其作用是const int *p与int *const p的结合。

int main() {int* q1 = nullptr;int* const q2 = nullptr;std::cout << typeid(q1).name() << std::endl;std::cout << typeid(q2).name() << std::endl;// const如果右边没有指针*的话,const是不参与类型的// 比如说下面的const p3,表明p3是一个常量,即指针的指向不能再做改变int a = 10;int* p1 = &a;const int* p2 = &a; // const int* 转换为 int*int* const p3 = &a; // int* 转换为 int*int* p4 = p3; //int* 转换为 int*return 0;
}

2.const和二级指针的结合

const和二级指针结合的几种方式

const int**q:const修饰的类型是int,而它修饰的表达式是**q,所以**q不能被赋值,但是*q可以被赋值,q本身可以被赋值。
int *const *q:const修饰的类型是int *,而它修饰的表达式是const *q,所以*q不能被赋值,但是**q可以被赋值,q本身也可以被赋值。
int ** const q:const修饰的类型是int**,而它修饰的表达式是q,所以q本身不能被赋值,但是*q和**q可以被赋值。

3.总结const和指针的类型转换公式

int* 转换为 const int* 是不可行的。
const int* 转换为 int* 是可行的。
int ** 转换为 const int** 是不可行的。
const int** 转换为 int **是不可行的。
int** 转换为int* const*是错误的。
int* const*转换为int**是可行的

4.const和一级指针,引用的结合使用

//写一句代码:在内存的0x0018ff44处写一个4字节的10
int *p = (int*)0x0018ff44;
int *const &p1 = (int*)0x0018ff44; //(非常量引用的初始值必须为左值)0x0018ff44已经为常量了,如果使用引用,需要使用const修饰
int *&&p2 = (int*)0x0018ff44; //也可以使用右值引用(什么是右值:没内存,没名字,即字面常量)

相关文章:

深入了解C++中const的用法

文章目录 一、C中的const如何理解&#xff1f;二、C中的const与C语言中的const有何区别&#xff1f;三、const与指针、引用的结合使用 一、C中的const如何理解&#xff1f; 在C中&#xff0c;const是一个关键字&#xff0c;用来表示常量性&#xff0c;意在告诉编译器某些变量或…...

【Linux金典面试题(上)】41道Linux金典面试问题+详细解答,包含基本操作、系统维护、网络配置、脚本编程等问题。

大家好&#xff0c;我是摇光~&#xff0c;用大白话讲解所有你难懂的知识点 之前写了一篇关于 python 的面试题&#xff0c;感觉大家都很需要&#xff0c;所以打算出一个面试专栏。 【数据分析岗】Python金典面试题 这个专栏主要针对面试大数据岗位、数据分析岗位、数据运维等…...

利用Python实现多元回归预测汽车价格

引言: AI技术的热门使得大家对机器学习有了更多的关注,作为与AI技术息息相关的一门课程,从头了解基础的机器学习算法就显得十分有必要,如:梯度下降,线性回归等。 正文: 本文将讲解线性回归中多元回回归的案例 机器学习大致可以分为监督学习,非监督学习、半监督学习还…...

抓包软件fiddler和wireshark使用手册

fiddler官方文档 Fiddler 抓包教程1 Fiddler 抓包教程2 wireshark抓包学习 2添加链接描述 ip 过滤 ip.src_host ip.dst_host ip.addr mac 过滤 eth.src eth.dst eth.addr 端口过滤 tcp.port tcp.srcport tcp.dstport 协议类型过滤 arp dhcp 规则组合 and or...

初识三大 Observer

文章目录 ResizeObserver、MutationObserver和IntersectionObserver用MutationObserver实现图片懒加载MutationObserver 兼容性问题IntersectionObserver 应用MutationObserver和IntersectionObserver的区别IntersectionObserver 实例示例一&#xff1a;图片懒加载示例二&#…...

Eclipse MAT(Memory Analyzer Tool) 使用手册

参考&#xff1a;JAVA内存泄露使用MAT(Memory Analyzer Tool)快速定位代码 Eclipse MAT 1.15.0提示JDK版本最低需要使用17版本的&#xff0c;如果不想安装可以下载ZIP包&#xff0c;或者使用较低版本的MAT。 为了避免下载的17版本JDK和本地环境干扰&#xff0c;可以直接在MAT配…...

TongWe7.0-东方通TongWeb控制台无法访问 排查

**问题描述&#xff1a;**无法访问TongWeb的控制台 逐项排查&#xff1a; 1、控制台访问地址是否正确&#xff1a;http://IP:9060/console #IP是服务器的实际IP地址 2、确认TongWeb进程是否存在&#xff0c;执行命令&#xff1a;ps -ef|grep tongweb 3、确认TongWeb服务启动…...

Ariba Procurement: Administration_Master data

采购主数据集成Procurement Master Data Integration 注意&#xff1a;并非所有元素都是必需的&#xff0c;数据元素的名称可能根据ERP的不同&#xff0c;有所不同。 Types of Master Data Accounting 在SAP Ariba中的各种会计元素字段中&#xff0c;填充有效值选择列表。建…...

爬虫学习案例4

爬取猪八戒网站数据&#xff1a;2024-12-12 使用xpath解析元素&#xff0c;安装依赖库 pip install lxml使用selenium步骤我的上篇博客有提到&#xff0c;这里就不重复了 selenium使用博客导航 # 安装pip install lxml,使用xpath from lxml import etree import time from s…...

Angular模块化应用构建详解

文章目录 前言一、理解Angular模块&#xff08;NgModule&#xff09;二、创建功能模块三、懒加载模块以提高性能四、共享模块五、库模块六、最佳实践与注意事项七、案例研究&#xff1a;重构电子商务平台结语 前言 Angular是一款由Google支持的、用于构建动态Web应用程序的前端…...

51c大模型~合集89

我自己的原文哦~ https://blog.51cto.com/whaosoft/12815167 #OpenAI很会营销 而号称超强AI营销的灵感岛实测成效如何&#xff1f; OpenAI 是懂营销的&#xff0c;连续 12 天发布&#xff0c;每天一个新花样&#xff0c;如今刚过一半&#xff0c;热度依旧不减。 毫无疑问&…...

【蓝桥杯备战】Day 1

1.基础题目 LCR 018.验证回文串 给定一个字符串 s &#xff0c;验证 s 是否是 回文串 &#xff0c;只考虑字母和数字字符&#xff0c;可以忽略字母的大小写。 本题中&#xff0c;将空字符串定义为有效的 回文串 。 示例 1: 输入: s "A man, a plan, a canal: Panama…...

FedAdam算法:供给方信用,数据质量;更新一致性

FedAdam算法:供给方信用,数据质量;更新一致性 FedAdam算法概述 FedAdam是一种联邦学习(Federated Learning)算法。联邦学习是一种机器学习技术,它允许在多个设备或数据中心(称为客户端)上训练模型,而无需将数据集中到一个中央服务器,从而保护数据隐私。FedAdam主要用于…...

内存卡格式化后的数据恢复全攻略

一、内存卡格式化简述 内存卡&#xff0c;作为现代电子设备中不可或缺的存储媒介&#xff0c;广泛应用于手机、相机、行车记录仪等各类设备中。然而&#xff0c;在使用过程中&#xff0c;我们可能会遇到内存卡需要格式化的情况。格式化是一种将内存卡上的所有数据和文件系统清…...

介绍交叉熵损失(Cross-Entropy Loss)以及交叉熵在对比学习中的应用:中英双语

中文版 本文解释 交叉熵损失&#xff08;Cross-Entropy Loss&#xff09;&#xff0c;并结合对比学习的应用说明它如何工作&#xff0c;以及如何让正样本对更近、负样本对更远。 什么是交叉熵损失&#xff1f; 交叉熵损失是机器学习中常用的一种损失函数&#xff0c;主要用于…...

RabbitMQ的几个概念

注&#xff1a;这篇文章会随时添加新的内容&#xff0c;就是将RabbtiMQ中的概念添加到这里。助力大家的学习 自动ACK和手动ACK的区别 自动ACK和手动ACK是消息队列中两种不同的消息确认机制&#xff0c;它们在消息处理的可靠性和灵活性方面存在显著差异。 自动ACK&#xff08…...

Ollama部署大模型并安装WebUi

Ollama用于在本地运行和部署大型语言模型(LLMs)的工具,可以非常方便的部署本地大模型 安装 Linux curl -fsSL https://ollama.com/install.sh | sh我是ubuntu系统安装,其他系统可以看项目的开源地址有写 GitHub - ollama/ollama: Get up and running with Llama 3, Mist…...

Debedium如何忽略Oracle的purge命令

报错 截至目前3.0版本&#xff0c;Debezium的Oracle Connector并不支持purge table这个指令。 所以&#xff0c;在使用Debezium解析Oracle变更的时候&#xff0c;如果在源端执行了类似 purge table "$BIN… 的语句&#xff0c;就会导致Debezium罢工&#xff0c;日志里显…...

PlantUML 语言

PlantUML 是一种开源工具&#xff0c;用于通过简单的文本描述生成 UML 图。它支持多种 UML 图类型&#xff0c;如类图、序列图、用例图、活动图、组件图、状态图等。PlantUML 语言非常简洁&#xff0c;采用类似编程语言的语法&#xff0c;允许用户使用文本定义模型&#xff0c;…...

linux的 .so和.ko文件分别是什么?主要区别是什么?

前言&#xff1a; .so和.ko文件的主要区别在于它们的应用层次和功能不同。‌ 应用层次 .so文件‌&#xff1a;这是用户层的动态链接库&#xff08;Shared Object&#xff09;&#xff0c;主要用于用户态的程序中。 它用于动态链接&#xff0c;多个程序可以共享同一个库文件&…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度​

一、引言&#xff1a;多云环境的技术复杂性本质​​ 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时&#xff0c;​​基础设施的技术债呈现指数级积累​​。网络连接、身份认证、成本管理这三大核心挑战相互嵌套&#xff1a;跨云网络构建数据…...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题

分区配置 (ptab.json) img 属性介绍&#xff1a; img 属性指定分区存放的 image 名称&#xff0c;指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件&#xff0c;则以 proj_name:binary_name 格式指定文件名&#xff0c; proj_name 为工程 名&…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下&#xff0c;卢森堡罗伯特舒曼医院&#xff08;the Robert Schuman Hospitals, HRS&#xff09;凭借在无菌制剂生产流程中引入增强现实技术&#xff08;AR&#xff09;创新项目&#xff0c;荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化

缓存架构 代码结构 代码详情 功能点&#xff1a; 多级缓存&#xff0c;先查本地缓存&#xff0c;再查Redis&#xff0c;最后才查数据库热点数据重建逻辑使用分布式锁&#xff0c;二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...

Linux 中如何提取压缩文件 ?

Linux 是一种流行的开源操作系统&#xff0c;它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间&#xff0c;使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的&#xff0c;要在 …...

redis和redission的区别

Redis 和 Redisson 是两个密切相关但又本质不同的技术&#xff0c;它们扮演着完全不同的角色&#xff1a; Redis: 内存数据库/数据结构存储 本质&#xff1a; 它是一个开源的、高性能的、基于内存的 键值存储数据库。它也可以将数据持久化到磁盘。 核心功能&#xff1a; 提供丰…...

Python 高效图像帧提取与视频编码:实战指南

Python 高效图像帧提取与视频编码:实战指南 在音视频处理领域,图像帧提取与视频编码是基础但极具挑战性的任务。Python 结合强大的第三方库(如 OpenCV、FFmpeg、PyAV),可以高效处理视频流,实现快速帧提取、压缩编码等关键功能。本文将深入介绍如何优化这些流程,提高处理…...

水泥厂自动化升级利器:Devicenet转Modbus rtu协议转换网关

在水泥厂的生产流程中&#xff0c;工业自动化网关起着至关重要的作用&#xff0c;尤其是JH-DVN-RTU疆鸿智能Devicenet转Modbus rtu协议转换网关&#xff0c;为水泥厂实现高效生产与精准控制提供了有力支持。 水泥厂设备众多&#xff0c;其中不少设备采用Devicenet协议。Devicen…...

Python网页自动化Selenium中文文档

1. 安装 1.1. 安装 Selenium Python bindings 提供了一个简单的API&#xff0c;让你使用Selenium WebDriver来编写功能/校验测试。 通过Selenium Python的API&#xff0c;你可以非常直观的使用Selenium WebDriver的所有功能。 Selenium Python bindings 使用非常简洁方便的A…...