【C++指南】类和对象(十):const成员函数
💓 博客主页:倔强的石头的CSDN主页
📝Gitee主页:倔强的石头的gitee主页
⏩ 文章专栏:《C++指南》
期待您的关注
目录
引言
一、const成员函数的定义与语法
1. 基本语法
2. 底层原理
二、const成员函数的作用与约束
1. 保障数据安全
2. 与const对象的关系
三、特殊场景与进阶技巧
1. mutable关键字
2. 函数重载
3. 权限传递规则
四、最佳实践与常见误区
1. 编码规范建议
2. 易错点分析
五、总结
引言
在C++中,const成员函数是面向对象编程中保障数据安全性的重要机制。它通过限制函数对类成员的修改权限,提升代码的健壮性和可维护性。
本文将结合代码示例,从语法、原理到实际应用场景,全面解析const成员函数的核心要点。
一、const成员函数的定义与语法
1. 基本语法
在成员函数的参数列表后添加const关键字,表明该函数不会修改类的非静态数据成员。
声明与定义需保持一致,否则编译器会视为不同函数,导致链接错误
class Student {
private:string name;int score;
public:// 声明为const成员函数const string& getName() const;
};// 定义时必须加const
const string& Student::getName() const {return name;
}
2. 底层原理
const成员函数通过修改隐式this指针的类型实现限制:
也就是说const成员函数,参数列表后边的const实际是修饰隐藏的this指针
-
普通成员函数:
void func(A* const this) -
const成员函数:
void func(const A* const this)
即const成员函数的this指针指向的对象不可被修改,
二、const成员函数的作用与约束
1. 保障数据安全
-
禁止修改成员变量:若在
const函数中尝试修改非mutable成员,编译器直接报错 -
允许访问静态成员:静态成员不属于对象,可被修改
class A {static int count;
public:void increment() const { count++; } // 合法
};
2. 与const对象的关系
-
const对象只能调用const成员函数:违反此规则会导致编译错误
-
非const对象优先调用非const版本:若无匹配的非const函数,则调用const版本(权限可以缩小,不能放大,非const对象调用const函数相当于原本可以读写,现在变为只读了)
const Student stu("Alice");
stu.getName(); // 必须调用const版本
简单来说:
- 普通对象可以调用const成员函数和普通成员函数,const对象只能调用const成员函数
三、特殊场景与进阶技巧
1. mutable关键字
若需在const函数中修改某些成员,可用mutable修饰该变量。常用于缓存、状态标记等场景
class Date {
private:mutable int accessCount; // 可被const函数修改
public:void logAccess() const { accessCount++; }
};
2. 函数重载
const成员函数可与非const版本构成重载,编译器根据对象常量性选择调用:
class Screen {
public:char get(int x, int y); // 非const版本char get(int x, int y) const; // const版本
};const Screen cs;
cs.get(0, 0); // 调用const版本
const对象只能调用const函数,普通对象优先调用普通成员函数
3. 权限传递规则(重要)
-
const函数不能调用非const函数:避免间接修改成员(权限放大)
-
非const函数可调用const函数:权限缩小是安全的
四、最佳实践与常见误区
1. 编码规范建议
-
所有只读函数声明为const:如
getter方法,提升接口安全性 -
谨慎使用mutable:过度使用会破坏
const语义,建议仅用于逻辑状态变量
2. 易错点分析
-
返回非const引用:若
const函数返回成员的非const引用,可能通过返回值意外修改数据
// 错误示例:通过返回值修改name
string& Student::getName() const { return name; // 编译错误!需返回const string&
}
五、总结
const成员函数通过限制函数行为,显著增强代码的鲁棒性。其核心价值体现在:
-
明确语义:标识函数为“只读”操作,提升代码可读性。
-
支持常量对象:确保const对象仅调用安全函数。
-
编译器辅助检查:在编译阶段捕获非法修改行为。
正确使用const成员函数,是编写高质量C++代码的重要习惯。
参考实现与扩展阅读
-
《Effective C++》:条款3“尽可能使用const”
-
《C++ Primer》:第7章“类”
相关文章:
【C++指南】类和对象(十):const成员函数
💓 博客主页:倔强的石头的CSDN主页 📝Gitee主页:倔强的石头的gitee主页 ⏩ 文章专栏:《C指南》 期待您的关注 目录 引言 一、const成员函数的定义与语法 1. 基本语法 2. 底层原理 二、const成员函数的作用与约束…...
数值分析与科学计算导引——误差与算法举例
文章目录 第一章 数值分析与科学计算导引1.1 数值分析的对象、作用与特点数值分析的对象数值分析的作用数值分析的特点 1.2 数值计算的误差误差分类误差与有效数字数值运算的误差估计 1.3 算法举例秦九韶算法求多项式值开根号迭代算法牛顿切线加权平均的松弛技术 第一章 数值分…...
ubuntu安装docker 无法拉取问题
sudo docker run hello-world [sudo] ubuntu 的密码: Unable to find image hello-world:latest locally docker: Error response from daemon: Get "https://registry-1.docker.io/v2/": context deadline exceeded (Client.Timeout exceeded while awai…...
【C++项目】Rpc通信框架设计
目录 Rpc远程调用的思想 项目框架设计 服务端模块划分 网络通信模块 Network 应用层通信协议模块 Protocol 消息分发处理模块 Dispatcher 远程调用路由功能模块 RpcRouter 编辑 发布订阅功能模块 Publish-Subscribe 服务注册/发现/上线/下线功能模块 Registry-Disc…...
八股取士--dockerk8s
一、Docker 基础 Docker 和虚拟机的区别是什么? 答案: 虚拟机(VM):虚拟化硬件,每个 VM 有独立操作系统,资源占用高,启动慢。Docker:容器化应用,共享宿主机内核…...
Autojs: 使用 SQLite
例子 let db new SQLiteUtil("/sdcard/A_My_DB/sqlite.db");db.fastCreateTable("user_table",{name: "",online: false,},["name"] // 设置 name 为唯一, 重复项 不会添加成功 );// 新增数据的 ID let row_id db.insert("use…...
思科、华为、H3C常用命令对照表
取消/关闭 思科no华为undo华三undo 查看 思科show华为display华三display 退出 思科exit华为quit华三quit 设备命名 思科hostname华为sysname华三sysname 进入全局模式 思科enable、config terminal华为system-view华三system-view 删除文件 思科delete华为delete华…...
解决 `pip is configured with locations that require TLS/SSL` 错误
问题描述 在使用 pip 安装 Python 包时,可能会遇到以下错误: WARNING: pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.这意味着 Python 的 ssl 模块未正确安装或配置,导致 p…...
2025-arXiv-OmniThink:通过思考扩展机器写作的知识边界
arXiv | https://arxiv.org/abs/2501.09751 GitHub | https://github.com/zjunlp/OmniThink 项目主页 | https://zjunlp.github.io/project/OmniThink/ ModelScope 在线 Demo | https://www.modelscope.cn/studios/iic/OmniThink 摘要: 大语言模型驱动的机器写作通…...
【广州大学主办,发表有保障 | IEEE出版,稳定EI检索,往届见刊后快至1个月检索】第二届电气技术与自动化工程国际学术会议 (ETAE 2025)
第二届电气技术与自动化工程国际学术会议 (ETAE 2025) The 2nd International Conference on Electrical Technology and Automation Engineering 大会官网:http://www.icetae.com/【更多详情】 会议时间:2025年4月25-27日 会议地点:…...
机器学习:01数学基础教程
函数 极限 按照一定次数排列的一列数:“,“,…,"…,其中u 叫做通项。 对于数列{Un}如果当n无限增大时,其通项无限接近于一个常数A,则称该数列以A为极限或称数列收敛于A,否则称数列为发散, 极限值 左…...
仿叮咚买菜鸿蒙原生APP
# DingdongShopping 这是一个原生鸿蒙版的仿叮咚买菜APP项目 鸿蒙Next发布至今已经有一年多的时间了,但有时候我们想要实现一些复杂的功能或者效果,在开发文档上查阅一些资料还是比较费时的,有可能还找不到我们想要的内容。而社会层面上分享…...
WordPress“更新失败,响应不是有效的JSON响应”问题的修复
在使用WordPress搭建网站时,许多人在编辑或更新文章时,可能会遇到一个提示框,显示“更新失败,响应不是有效的JSON响应”。这个提示信息对于不了解技术细节的用户来说,太难懂。其实,这个问题并不复杂&#x…...
kotlin的onFailure: () -> Unit
在Kotlin中,onFailure: () -> Unit表示一个没有参数且返回类型为Unit的函数。 在Kotlin中,Unit类型用于表示那些没有返回值的函数。具体来说,() -> Unit表示一个没有参数的函数,其返回类型为Unit。这种函数通常用于表示…...
通过网线将Keysight DSOX4154A示波器信号传输至电脑的Step
一、硬件连接 连接网线 使用标准以太网线(Cat5e或更高)连接示波器背面的 LAN端口 至电脑或同一局域网的交换机/路由器。 二、示波器网络配置 进入网络设置菜单 点击示波器前面板右上角 【Utility】 → 【I/O】 → 【LAN Settings】。 配置IP地址 自…...
midjourney 一 prompt 提示词
midjourney 不需要自然语言的描述,它只需要关键词即可。 一个完整的Midjourney prompt通常包括三个部分 图片提示(Image Prompts)、文本提示(Text Prompt)和参数(Parameters)。 1、图片提示(…...
微信小程序 - 网络请求基础路径集中管理(基础路径集中管理策略、动态切换基础路径)
一、基础路径集中管理 在微信小程序项目开发中,经常会将请求的基础路径集中管理 这样可以避免在多个页面中重复定义,同时也方便后续维护与修改 二、基础路径集中管理策略 1、使用全局变量 微信小程序提供了 App 对象,可以在 app.js 中定义…...
C#的委托delegate与事件event
在C#中,delegate(委托)和 event(事件)是两个非常重要的概念,它们主要用于实现回调机制和事件驱动编程。下面详细介绍它们的原理和使用场景。 1. Delegate(委托) 1.1 委托的原理 委托…...
apache artemis安装
安装apache artemis https://xxzkid.github.io/2025/apache-artemis-install...
Lightning基础训练尝试实例
一、训练任务概述 动机:由于后续的课题中会用到类似图像去噪的算法,考虑先用U-Net,这里做一个前置的尝试。 训练任务:分割出图像中的细胞。 数据集:可私 数据集结构: 二、具体实现 U-Net的网络实现是现…...
大模型评估与对齐:核心挑战与实践指南
1. 大模型评估与对齐的核心挑战当我们谈论大语言模型时,评估和对齐这两个概念就像硬币的两面。评估是测量模型表现的过程,而对齐则是确保模型行为符合人类期望的持续调整。这听起来简单,实际操作中却充满微妙挑战。评估的难点在于,…...
零基础转行项目管理,到底要不要考 PMP?
很多零基础想转行项目管理的朋友,都绕不开一个灵魂拷问:花几千块考PMP,到底值不值?不考证就找不到工作吗?作为深耕行业十多年的老PM,今天用最直白的话讲透,帮你精准决策,不花冤枉钱&…...
可微光栅化技术:3D场景重建与实时渲染新突破
1. 可微三角形光栅化技术解析1.1 传统光栅化的局限性传统图形管线中的光栅化过程是一个离散化操作,它将连续的几何形状转换为离散的像素阵列。这个过程中最关键的步骤是将三角形从3D空间投影到2D屏幕空间,并确定哪些像素被三角形覆盖。然而,这…...
阿里提出 SkillRouter:1.2B 小模型解决 8 万技能路由难题
📌 一句话总结: 本文提出 SKILLROUTER,一个 1.2B 参数的全文检索—重排路由管线,在约 8 万技能池上取得 74.0% Hit1,以 13 更少参数和 5.8 更低延迟超越 16B 强基线。 🔍 背景问题: 随着 LLM…...
STM32 HAL库避坑实录:F103C8T6定时器配置那些CubeMX没告诉你的细节(附示波器验证)
STM32 HAL库避坑实录:F103C8T6定时器配置那些CubeMX没告诉你的细节(附示波器验证) 在嵌入式开发中,定时器是最基础也是最复杂的外设之一。对于使用STM32F103C8T6这类入门级MCU的开发者来说,CubeMX和HAL库的组合确实大大…...
XInputTest终极指南:如何精确测量Xbox控制器轮询性能与延迟
XInputTest终极指南:如何精确测量Xbox控制器轮询性能与延迟 【免费下载链接】XInputTest Xbox 360 Controller (XInput) Polling Rate Checker 项目地址: https://gitcode.com/gh_mirrors/xin/XInputTest 你是否曾在激烈的游戏对抗中,明明按下了按…...
六自由度串联机械臂运动规划及跟踪动力学【附代码】
✅ 博主简介:擅长数据搜集与处理、建模仿真、程序设计、仿真代码、论文写作与指导,毕业论文、期刊论文经验交流。 ✅ 如需沟通交流,扫描文章底部二维码。(1)基于改进RRT*-Connect与五次多项式插值的轨迹规划࿱…...
2026年韦尔股份数字IC设计笔试题带答案
考试时间:90分钟 总分:100分 一、单选题(每题3分,共24分) 关于阻塞赋值(=)与非阻塞赋值(<=),下列说法正确的是: A. 时序逻辑中应使用阻塞赋值 B. 组合逻辑中应使用非阻塞赋值 C. 同一always块内可以混合使用两种赋值 D. 时序逻辑中使用非阻塞赋值,组合逻辑中…...
Laurentianelle
前言 在使用 kubectl get $KIND -o yaml 查看 k8s 资源时,输出结果中包含大量由集群自动生成的元数据(如 managedFields、resourceVersion、uid 等)。这些信息在实际复用 yaml 清单时需要手动清理,增加了额外的工作量。 使用 ku…...
别再死记硬背Mask RCNN结构了!用PyTorch手撸一遍,从RPN到ROIAlign全搞懂
从零实现Mask RCNN:用PyTorch拆解RPN与ROIAlign核心逻辑 当你第一次翻开Mask RCNN论文时,那些密密麻麻的结构图是否让你望而生畏?作为Faster RCNN的升级版,这个看似复杂的模型其实由几个精妙模块组合而成。本文将用PyTorch代码逐…...
