当前位置: 首页 > 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;多个程序可以共享同一个库文件&…...

设计模式和设计原则回顾

设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

基于Flask实现的医疗保险欺诈识别监测模型

基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施&#xff0c;由雇主和个人按一定比例缴纳保险费&#xff0c;建立社会医疗保险基金&#xff0c;支付雇员医疗费用的一种医疗保险制度&#xff0c; 它是促进社会文明和进步的…...

postgresql|数据库|只读用户的创建和删除(备忘)

CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

MySQL中【正则表达式】用法

MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现&#xff08;两者等价&#xff09;&#xff0c;用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例&#xff1a; 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南

文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/55aefaea8a9f477e86d065227851fe3d.pn…...

Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理

引言 Bitmap&#xff08;位图&#xff09;是Android应用内存占用的“头号杀手”。一张1080P&#xff08;1920x1080&#xff09;的图片以ARGB_8888格式加载时&#xff0c;内存占用高达8MB&#xff08;192010804字节&#xff09;。据统计&#xff0c;超过60%的应用OOM崩溃与Bitm…...

Go 并发编程基础:通道(Channel)的使用

在 Go 中&#xff0c;Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式&#xff0c;用于在多个 Goroutine 之间传递数据&#xff0c;从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...

计算机基础知识解析:从应用到架构的全面拆解

目录 前言 1、 计算机的应用领域&#xff1a;无处不在的数字助手 2、 计算机的进化史&#xff1a;从算盘到量子计算 3、计算机的分类&#xff1a;不止 “台式机和笔记本” 4、计算机的组件&#xff1a;硬件与软件的协同 4.1 硬件&#xff1a;五大核心部件 4.2 软件&#…...

高防服务器价格高原因分析

高防服务器的价格较高&#xff0c;主要是由于其特殊的防御机制、硬件配置、运营维护等多方面的综合成本。以下从技术、资源和服务三个维度详细解析高防服务器昂贵的原因&#xff1a; 一、硬件与技术投入 大带宽需求 DDoS攻击通过占用大量带宽资源瘫痪目标服务器&#xff0c;因此…...

rm视觉学习1-自瞄部分

首先先感谢中南大学的开源&#xff0c;提供了很全面的思路&#xff0c;减少了很多基础性的开发研究 我看的阅读的是中南大学FYT战队开源视觉代码 链接&#xff1a;https://github.com/CSU-FYT-Vision/FYT2024_vision.git 1.框架&#xff1a; 代码框架结构&#xff1a;readme有…...