C++ 中 const 关键字
C++ 中 const 关键字
2009-02-19
2024-07-23 补充C++11后的做法
在 C++ 中,const 是一个关键字(也称为保留字),它用于指定变量或对象的值在初始化后不能被修改。关键字是编程语言中具有特殊含义的词汇,编译器会识别这些词并对其进行特殊处理。
类型限定符(Type Qualifier)是指在编程语言中用来限定或修饰变量类型的关键字,它们提供额外的信息来约束变量的行为或存储方式。在 C++ 中,常见的类型限定符包括 const、volatile 和 mutable。
在这里主要说 const 。
const 是一个类型限定符,用于声明常量或只读数据。它表示一旦变量被初始化,其值不能被修改。const 关键字可以应用于变量、指针、引用、函数参数、返回值、成员函数和成员变量。用于声明常量或者指定某个变量、对象的成员、函数参数或返回值的某些方面是不可修改的。
使用 const
关键字编写高质量的代码。
常量声明(Constant Declaration)
用 const
定义常量以替代魔法数字(magic numbers),增加代码的可读性。
#include <iostream>const int MAX_SIZE = 100;int main() {int arr[MAX_SIZE]; // 使用常量声明数组大小std::cout << "Array size: " << MAX_SIZE << std::endl;return 0;
}
常量声明是指用 const
关键字声明一个不可变的变量。
#include <iostream>int main() {const int constantValue = 42; // 声明一个常量变量// constantValue = 10; // 错误:不能修改常量变量的值std::cout << "constantValue: " << constantValue << std::endl;return 0;
}
枚举类型的枚举值
枚举类型中的枚举值默认是整数类型,虽然不能直接指定为 const
,但它们在概念上是常量,不可修改。
enum Colors {RED,GREEN,BLUE
};int main() {Colors color = RED;// color = 10; // 错误:不能将整型赋值给枚举类型return 0;
}
只读引用(Read-Only Reference)
使用 const
引用传递参数,避免拷贝,提高函数效率,并防止修改传入的参数。
示例1
#include <iostream>void printVector(const std::vector<int>& vec) {for (const int& elem : vec) {std::cout << elem << " ";}std::cout << std::endl;
}int main() {std::vector<int> vec = {1, 2, 3, 4, 5};printVector(vec); // 通过只读引用传递vectorreturn 0;
}
示例2
#include <iostream>// 使用常量引用作为函数参数
void printValue(const int& value) {// value = 20; // 错误:不能修改通过常量引用传递的值std::cout << "Value: " << value << std::endl;
}int main() {int x = 10;printValue(x);return 0;
}
函数参数(Function Parameters)
函数参数使用 const
修饰以防止函数内部修改传入的参数。
#include <iostream>void processArray(const int* array, const int size) {for (int i = 0; i < size; ++i) {std::cout << array[i] << " ";}std::cout << std::endl;
}int main() {int arr[] = {1, 2, 3, 4, 5};processArray(arr, 5); // 使用const指针传递数组return 0;
}
返回值(Return Value)
使用 const
修饰返回值,确保返回的对象不能被修改,保护数据完整性。
#include <iostream>const std::string& getGreeting() {static const std::string greeting = "Hello, World!";return greeting;
}int main() {const std::string& greet = getGreeting();std::cout << greet << std::endl;// greet = "Hi"; // 错误:不能修改const引用return 0;
}
成员函数限定符(Member Function Qualifier)
类的成员函数使用 const
限定符,确保函数不会修改对象的状态。
#include <iostream>class MyClass {
public:MyClass(int value) : value_(value) {}int getValue() const {return value_;}void printValue() const {std::cout << "Value: " << value_ << std::endl;}private:int value_;
};int main() {MyClass obj(10);obj.printValue(); // 调用const成员函数return 0;
}
成员变量(Member Variable)
类的成员变量使用 const
修饰,确保其在初始化后不会被修改。
#include <iostream>class MyClass {
public:MyClass(int value) : value_(value) {}int getValue() const {return value_;}private:const int value_; // const成员变量
};int main() {MyClass obj(10);std::cout << "Value: " << obj.getValue() << std::endl;return 0;
}
迭代器和指针(Iterators and Pointers)
使用 const
修饰迭代器和指针,确保它们指向的值不会被修改。
#include <iostream>
#include <vector>int main() {std::vector<int> vec = {1, 2, 3, 4, 5};std::vector<int>::const_iterator it;for (it = vec.begin(); it != vec.end(); ++it) {std::cout << *it << " ";// *it = 10; // 错误:不能通过const迭代器修改值}std::cout << std::endl;return 0;
}
常量指针
#include <iostream>int main() {int value = 10;int otherValue = 20;// 常量指针:指针本身是常量,不能指向其他地方int* const ptr = &value;*ptr = 30; // 可以修改指针指向的值// ptr = &otherValue; // 错误:不能修改指针本身// 指向常量的指针:不能通过指针修改指向的值const int* ptrToConst = &value;// *ptrToConst = 40; // 错误:不能修改指针指向的值ptrToConst = &otherValue; // 可以改变指针本身// 指向常量的常量指针:指针本身和指针指向的值都不能修改const int* const constPtrToConst = &value;// *constPtrToConst = 50; // 错误:不能修改指针指向的值// constPtrToConst = &otherValue; // 错误:不能修改指针本身std::cout << "value = " << value << std::endl;return 0;
}
多态和虚函数(Polymorphism and Virtual Functions)
在多态和虚函数中使用 const
修饰,确保基类和派生类接口一致,并且保证对象状态不被修改。
#include <iostream>class Base {
public:virtual void show() const { // const虚函数std::cout << "Base show" << std::endl;}
};class Derived : public Base {
public:void show() const override { // 覆盖const虚函数std::cout << "Derived show" << std::endl;}
};int main() {Base* b = new Derived();b->show(); // 调用派生类的const虚函数delete b;return 0;
}
函数返回类型后缀(Const After Function Return Type)
函数返回类型可以在函数名后面添加 const
,这种用法一般用于操作符重载,确保返回的对象不能被修改。
#include <iostream>class MyClass {
public:MyClass(int value) : value_(value) {}// 返回一个常量对象const MyClass& operator+(const MyClass& other) const {static MyClass result(value_ + other.value_);return result;}int getValue() const {return value_;}private:int value_;
};int main() {MyClass a(10);MyClass b(20);const MyClass& c = a + b; // 确保返回的对象不能被修改std::cout << "Value of c: " << c.getValue() << std::endl;// c.setValue(50); // 错误:不能修改常量对象return 0;
}
constexpr 和 const
constexpr
是 C++11 引入的关键字,表示一个常量表达式。在 constexpr
中,const
是隐含的,因此 constexpr
对象也是常量。
#include <iostream>constexpr int square(int x) {return x * x;
}int main() {constexpr int result = square(10); // 在编译时计算结果std::cout << "Square of 10 is " << result << std::endl;return 0;
}
lambda 表达式捕获列表
在 lambda 表达式的捕获列表中,可以使用 const
来确保捕获的变量不会在 lambda 内部被修改。
#include <iostream>int main() {int value = 10;auto lambda = [value]() mutable {// value = 20; // 错误:不能修改捕获的常量std::cout << "Captured value: " << value << std::endl;};lambda();return 0;
}
引用成员变量中的 const
在类中,成员变量也可以是常量引用,这种情况一般用于引用另一个对象的常量属性。
#include <iostream>class MyClass {
public:MyClass(const int& ref) : ref_(ref) {}int getValue() const {return ref_;}private:const int& ref_; // 常量引用成员变量
};int main() {int value = 42;MyClass obj(value);std::cout << "Value: " << obj.getValue() << std::endl;return 0;
}
mutable 与 const 成员变量
mutable
关键字允许我们在 const
成员函数中修改特定的成员变量。
#include <iostream>class MyClass {
public:MyClass(int value) : value_(value), counter_(0) {}int getValue() const {++counter_; // 可以修改 mutable 成员变量return value_;}int getCounter() const {return counter_;}private:int value_;mutable int counter_; // mutable 成员变量
};int main() {MyClass obj(10);std::cout << "Value: " << obj.getValue() << std::endl;std::cout << "Counter: " << obj.getCounter() << std::endl;return 0;
}
volatile 与 const
volatile
关键字表示一个变量可能在程序的控制之外被修改,比如在多线程环境中。可以同时使用 volatile
和 const
修饰一个变量,表示变量是只读的,但其值可能会被外部因素修改。
#include <iostream>volatile const int* ptr; // 指向 volatile 和 const 的指针int main() {static int value = 42;ptr = &value;std::cout << "Value: " << *ptr << std::endl;return 0;
}
const_cast
const_cast
用于移除 const
限定符,但要谨慎使用,因为这可能导致未定义行为。
#include <iostream>void modifyValue(const int& value) {int& nonConstValue = const_cast<int&>(value);nonConstValue = 20;
}int main() {int x = 10;std::cout << "Before: " << x << std::endl;modifyValue(x);std::cout << "After: " << x << std::endl;return 0;
}
static const 数据成员
类的 static const
数据成员可以存储类级别的常量信息,通常需要在类外部初始化。
#include <iostream>class MyClass {
public:static const int staticValue;
};const int MyClass::staticValue = 42; // 在类外部初始化int main() {std::cout << "Static Value: " << MyClass::staticValue << std::endl;return 0;
}
相关文章:
C++ 中 const 关键字
C 中 const 关键字 2009-02-19 2024-07-23 补充C11后的做法 在 C 中,const 是一个关键字(也称为保留字),它用于指定变量或对象的值在初始化后不能被修改。关键字是编程语言中具有特殊含义的词汇,编译器会识别这些词并…...

客梯自动监测识别摄像机
当今社会,随着城市建设的快速发展,客梯作为现代化建筑不可或缺的一部分,其安全性与效率显得尤为重要。为了提升客梯的安全管理水平,智能监测技术应运而生,尤其是客梯自动监测识别摄像机系统的应用,为乘客和…...

为什么那么多人学习AI绘画?工资香啊!
在当今这个科技日新月异的时代,AI绘画作为数字艺术与人工智能融合的璀璨成果,正吸引着无数人投身其中,而“工资香啊!”无疑是这一热潮背后不可忽视的驱动力之一。 AI绘画的高薪待遇是吸引众多学习者的关键因素。随着市场对AI艺术…...

国产JS库(js-tool-big-box)7月度总结
js-tool-big-box开发已经有3个月了,团队内的小伙伴进行了热烈的讨论,持续做了功能迭代。小伙伴们也做了艰苦卓绝的文档分享,有纯功能分享类的,有带有小故事的,有朋友们利用自己独自网站分发分享的。7月份快要结束了&am…...

c++ 高精度加法(只支持正整数)
再给大家带来一篇高精度,不过这次是高精度加法!话不多说,开整! 声明 与之前那篇文章一样,如果看起来费劲可以结合总代码来看 定义 由于加法进位最多进1位,所以我们的结果ans[]的长度定义为两个加数中最…...
python键盘操作工具:ctypes、pyautogui
这里模拟 Win Ctrl L 组合键 1、ctypes ctypes库,它允许我们直接调用Windows API来模拟键盘输入。 import ctypes import time# 定义所需的常量和结构 LONG ctypes.c_long DWORD ctypes.c_ulong ULONG_PTR ctypes.POINTER(DWORD) WORD ctypes.c_ushortclass…...
计算机网络发展历史
定义和基本概念 计算机网络是由多个计算设备通过通信线路连接起来的集合,这些设备能够互相交换数据、消息和资源。计算机网络的核心功能是实现数据的远程传输和资源共享,它使得地理位置的限制被大大减弱,极大地促进了信息的自由流动和人类社…...

记录安装android studio踩的坑 win7系统
最近在一台新电脑上安装android studio,报了很多错误,也是费了大劲才解决,发出来大家一起避免一些问题,找到解决方法。 安装时一定要先安装jdk,cmd命令行用java -version查当前的版本,没有的话,先安装jdk,g…...
Python图形编程-PyGame快速入门
PyGame快速入门 文章目录 PyGame快速入门1、什么是PyGame2、安装PyGame3、创建PyGame窗口4、处理事件5、绘制对象6、移动对象7、加载和显示图像8、播放声音9、处理用户输入10、碰撞检测11、动画精灵12、管理游戏状态13、Pygame 中的典型主游戏循环1、什么是PyGame Pygame 是一…...
邦芒宝典:8种方法调整职场心态
在职场中拼斗当然要有好的心态,您知道职场心态如何调整吗? 方法1:自我调整 “思想可以使天堂变成地狱,也可以使地狱变成天堂。”你不能样样顺利,但可以事事尽心;你不能左右天气,但可以改变心情;你…...

华为OD2024D卷机试题汇总,含D量50%+,按算法分类刷题,事半功倍
目录 专栏导读华为OD机试算法题太多了,知识点繁杂,如何刷题更有效率呢? 一、逻辑分析二、数据结构1、线性表① 数组② 双指针 2、map与list3、队列4、链表5、栈6、滑动窗口7、二叉树8、并查集9、矩阵 三、算法1、基础算法① 贪心思维② 二分查…...

Unity UGUI 之 Graphic Raycaster
本文仅作学习笔记与交流,不作任何商业用途 本文包括但不限于unity官方手册,唐老狮,麦扣教程知识,引用会标记,如有不足还请斧正 首先手册连接如下: Unity - Manual: Graphic Raycaster 笔记来源于ÿ…...

类和对象——相关的零碎知识
前提提示: 其实C中的类和对象,最重要的是6个默认函数,如有忘记,请移步到:类和对象。本章是对于一些细节知识的补充和拓展。 1. 隐示类型转换 在运算时,运算符左右两边的操作数的类型不同,编译器…...
【hadoop大数据集群 1】
hadoop大数据集群 1 文章目录 hadoop大数据集群 1一、环境配置1.安装虚拟机2.换源3.安装工具4.安装JDK5.安装Hadoop 一、环境配置 折腾了一下午/(ㄒoㄒ)/~~ 1.安装虚拟机 参考视频:https://www.bilibili.com/video/BV18y4y1G7JA?p17&vd_sourcee15e83ac6b22a…...

TQSDRPI开发板教程:实现PL端的UDP回环与GPSDO
本教程将完成一个全面的UDP运行流程与GPSDO测试,从下载项目的源代码开始,通过编译过程,最终将项目部署到目标板卡上运行演示。此外,我们还介绍如何修改板卡的IP地址,以便更好地适应您的网络环境或项目需求。 首先从Gi…...
array.some() ==> 查找数组list中,是否有包含与当前currKey的值不一样的misId
需求: const list [ {misId: e, name: 小白}, {misId: e, name: 小白白}, {misId: r, name: 小王}, {misId: r, name: 小小王} ] let currKey r 查找数组list中,是否有包含与当前currKey的值不一样的misId 解决: 要查找数组lis…...

最简单的typora+gitee+picgo配置图床
typoragiteepicgo图床 你是否因为管理图片而感到头大?是时候了解一下 Typora、Gitee 和 PicGo 这个超级三剑客了,它们可以帮你轻松打造自己的图床,让你的博客图片管理变得简单又有趣。让我们开始这场神奇的图床之旅吧! Typora …...
【黄啊码】GPT的相关名词解释
GPT是一种基于互联网的、可用数据来训练的、文本生成的深度学习模型 GPT的核心技术是变换器(Transformer),这是一种神经网络结构,可以有效地处理序列数据,比如文本、语音、图像等。GPT使用了大量的预训练数据&#…...
git stash 命令详解
git stash 描述 git stash 命令用于将当前工作目录中的未提交更改(包括暂存区和工作区的更改)保存到一个栈中,并恢复工作目录到干净的 HEAD 状态。这样您可以在不提交当前更改的情况下,切换到其他分支或进行其他操作。后续可以通…...

txt格式单词导入有道词典生词本 (java代码方式)
txt格式单词导入有道词典生词本 (java代码方式) 首先要求txt文档里单词的格式,大概需要像这种: 每行是一个单词,格式为:英文单词空格词性单词意思。 注意 导出单词本的名字就是你 txt 文件的名字 我这里是 公共英语三级 单词本 …...
内存分配函数malloc kmalloc vmalloc
内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...
java 实现excel文件转pdf | 无水印 | 无限制
文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

让AI看见世界:MCP协议与服务器的工作原理
让AI看见世界:MCP协议与服务器的工作原理 MCP(Model Context Protocol)是一种创新的通信协议,旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天,MCP正成为连接AI与现实世界的重要桥梁。…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

springboot整合VUE之在线教育管理系统简介
可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生,小白用户,想学习知识的 有点基础,想要通过项…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
腾讯云V3签名
想要接入腾讯云的Api,必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口,但总是卡在签名这一步,最后放弃选择SDK,这次终于自己代码实现。 可能腾讯云翻新了接口文档,现在阅读起来,清晰了很多&…...