【C++入门】const和mutable关键字、常函数介绍

2023-11-02

1、常函数介绍

1.1、什么是常函数

(1)常函数的定义:类的成员函数对类中任何成员不作修改而只能作访问的函数;简单来说,就是调用类的成员函数不会对类做任何修改;
(2)常函数的实现:常函数是依靠const关键字实现的,具体是在类中声明成员函数和实现成员函数时都用const关键字去修饰;

1.2、为什么需要常函数

(1)常函数是为了使用类的时候更安全。比如:有的成员函数只需要返回类的某些成员变量的值而不需要修改,就可以把这种成员函数定义成常函数,从语法上保证成员函数中不会修改;
(2)在C++项目的开发中,定义类(程序员A)和使用类(程序员B)的很可能是两个程序员,所以程序员之间约定一些规则。比如程序员B使用程序员A的定义的类,当程序员B看到类的成员函数被const修饰,就知道这是个常函数,调用这个成员函数不会修改对象的数据,可以放心使用;

1.3、使用常函数的好处

(1)首先要知道常函数是C++语言提供的一种机制,用来保证成员函数不会修改类的成员;但是就算C++不提供常函数机制,程序员也同样可以实现常函数的效果,只要程序员不在成员函数里修改类的成员即可;
(2)如果不使用常函数机制,那么就要靠程序员自己保证不在成员函数中修改类的成员变量。靠程序员去保证是不靠谱的,尤其是在大型程序中,所以常函数机制可以强制保证成员函数不会去修改成员变量;
(3)常函数可以让使用类的程序员明确知道调用成员函数不会修改类的成员变量。就和C语言用const去修饰函数的传参一样,明确表示函数不会修改传进来的参数;

2、C++中的const关键字

(1)const关键字在C语言中就有,C++兼容C,所以C中const的用法C++中全都支持,参考博客:《const关键字与指针》
(2)const修饰引用,主要用于函数传参,限制函数内部对实参进行修改;
(3)const修饰成员函数(常函数),限制成员函数在内部修改成员变量;

3、mutable关键字

(1)mutable的作用是突破const限制,有点和const的作用反着干的意思:const修饰成员函数让成员函数不能在内部修改成员变量,而mutable修饰成员变量,让常函数在内部又可以修改mutable修改的成员变量;
(2)const和mutable关键字,体现了C++语言给程序员预留了相当大的灵活度,程序员既可以用const去实现常函数,又可以用mutable去给某些成员变量特殊性,让常函数在内部可以修改用mutable修饰的成员变量;

4、示例代码

4.1、person.hpp

#ifndef PERSON_HPP
#define PERSON_HPP

#include <string>
using namespace std;

namespace MAN{

class Person{
public:
    int age;

	 //获取姓名,用const修饰成常函数,表示内部不会修改成员变量
    string getName(void) const; 
    
	 //构造函数
    Person(){};
    Person(string myname){this->name=myname; this->getNameCnt=0;};

private:
    string name;    //人的名字,不希望被修改
    mutable int getNameCnt; //名字被查询的次数

};

}
#endif // PERSON_HPP

4.2、person.cpp

#include "person.hpp"
#include <iostream>

using namespace std;

string MAN::Person::getName(void) const
{
	 //因为getNameCnt变量被mutable修饰,所以这里才可以修改 
    this->getNameCnt++;	
    cout << "getNameCnt=" << this->getNameCnt << endl;
    return this->name;
}

4.3、main.cpp

#include <iostream>
#include "person.hpp"

using namespace std;
using namespace MAN;

int main()
{
		//初始化name为linux
    Person p1("linux");

    cout << "p1.name=" << p1.getName() << endl;

    cout << "p1.name=" << p1.getName() << endl;

    cout << "p1.name=" << p1.getName() << endl;

    return 0;
}

4.4、代码执行结果

root@ubuntu:# ./app 
getNameCnt=1
p1.name=linux
getNameCnt=2
p1.name=linux
getNameCnt=3
p1.name=linux

4.5、代码分析

(1)Person类的getName成员函数被const修饰成常函数,但是getName函数在内部修改了getNameCnt成员变量,不是严格意义上的常函数;
(2)getNameCnt成员变量可以在常函数中被修改是因为用mutable修饰,突破了常函数的限制;
总结:C++的语法很灵活,像const和mutable几乎就是相反的两个特性,这些特性可以让程序员写出很多高效的代码,但同时也增加了学习C++语言的难度,如果没有理解这些语言特性就很可能看C++代码就看得云里雾里的;

5、推荐

我会在C++专栏持续根据更新C++相关的知识点,这里也给大家推荐一款学习C++的神器,我也是在用这一款神器在学习C++。
链接:学习神器跳转
如果你是想入门C++这门语言或者是找C++岗位的工作,都推荐你试试这个网站,里面有针对C++知识点的选择题、编程题,更有C++岗位的面试题
在这里插入图片描述
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【C++入门】const和mutable关键字、常函数介绍 的相关文章

  • 我如何才能等待多个事情

    我正在使用 C 11 和 stl 线程编写一个线程安全队列 WaitAndPop 方法当前如下所示 我希望能够将一些内容传递给 WaitAndPop 来指示调用线程是否已被要求停止 如果 WaitAndPop 等待并返回队列的元素 则应返回
  • 以文化中立的方式将字符串拆分为单词

    我提出了下面的方法 旨在将可变长度的文本拆分为单词数组 以进行进一步的全文索引处理 删除停止词 然后进行词干分析 结果似乎不错 但我想听听关于这种实现对于不同语言的文本的可靠性的意见 您会建议使用正则表达式来代替吗 请注意 我选择不使用 S
  • 为什么 C# Array.BinarySearch 这么快?

    我已经实施了一个很简单用于在整数数组中查找整数的 C 中的 binarySearch 实现 二分查找 static int binarySearch int arr int i int low 0 high arr Length 1 mid
  • 为什么两个不同的 Base64 字符串的转换会返回相等的字节数组?

    我想知道为什么从 base64 字符串转换会为不同的字符串返回相同的字节数组 const string s1 dg const string s2 dq byte a1 Convert FromBase64String s1 byte a2
  • 在哪里可以找到列出 SSE 内在函数操作的官方参考资料?

    是否有官方参考列出了 GCC 的 SSE 内部函数的操作 即 头文件中的函数 除了 Intel 的 vol 2 PDF 手册外 还有一个在线内在指南 https www intel com content www us en docs in
  • 用于登录 .NET 的堆栈跟踪

    我编写了一个 logger exceptionfactory 模块 它使用 System Diagnostics StackTrace 从调用方法及其声明类型中获取属性 但我注意到 如果我在 Visual Studio 之外以发布模式运行代
  • OleDbDataAdapter 未填充所有行

    嘿 我正在使用 DataAdapter 读取 Excel 文件并用该数据填充数据表 这是我的查询和连接字符串 private string Query SELECT FROM Sheet1 private string ConnectStr
  • 如何从 appsettings.json 文件中的对象数组读取值

    我的 appsettings json 文件 StudentBirthdays Anne 01 11 2000 Peter 29 07 2001 Jane 15 10 2001 John Not Mentioned 我有一个单独的配置类 p
  • 堆栈溢出:堆栈空间中重复的临时分配?

    struct MemBlock char mem 1024 MemBlock operator const MemBlock b const return MemBlock global void foo int step 0 if ste
  • C# 中通过 Process.Kill() 终止的进程的退出代码

    如果在我的 C 应用程序中 我正在创建一个可以正常终止或开始行为异常的子进程 在这种情况下 我通过调用 Process Kill 来终止它 但是 我想知道该进程是否已退出通常情况下 我知道我可以获得终止进程的错误代码 但是正常的退出代码是什
  • 显示UnityWebRequest的进度

    我正在尝试使用下载 assetbundle统一网络请求 https docs unity3d com ScriptReference Networking UnityWebRequest GetAssetBundle html并显示进度 根
  • 如何设计以 char* 指针作为类成员变量的类?

    首先我想介绍一下我的情况 我写了一些类 将 char 指针作为私有类成员 而且这个项目有 GUI 所以当单击按钮时 某些函数可能会执行多次 这些类是设计的单班在项目中 但是其中的某些函数可以执行多次 然后我发现我的项目存在内存泄漏 所以我想
  • 如何在整个 ASP .NET MVC 应用程序中需要授权

    我创建的应用程序中 除了启用登录的操作之外的每个操作都应该超出未登录用户的限制 我应该添加 Authorize 每个班级标题前的注释 像这儿 namespace WebApplication2 Controllers Authorize p
  • 如何序列化/反序列化自定义数据集

    我有一个 winforms 应用程序 它使用强类型的自定义数据集来保存数据进行处理 它由数据库中的数据填充 我有一个用户控件 它接受任何自定义数据集并在数据网格中显示内容 这用于测试和调试 为了使控件可重用 我将自定义数据集视为普通的 Sy
  • 链接器错误:已定义

    我尝试在 Microsoft Visual Studio 2012 中编译我的 Visual C 项目 使用 MFC 但出现以下错误 error LNK2005 void cdecl operator new unsigned int 2
  • 向现有 TCP 和 UDP 代码添加 SSL 支持?

    这是我的问题 现在我有一个 Linux 服务器应用程序 使用 C gcc 编写 它与 Windows C 客户端应用程序 Visual Studio 9 Qt 4 5 进行通信 是什么very在不完全破坏现有协议的情况下向双方添加 SSL
  • 基于 OpenCV 边缘的物体检测 C++

    我有一个应用程序 我必须检测场景中某些项目的存在 这些项目可以旋转并稍微缩放 更大或更小 我尝试过使用关键点检测器 但它们不够快且不够准确 因此 我决定首先使用 Canny 或更快的边缘检测算法 检测模板和搜索区域中的边缘 然后匹配边缘以查
  • IEnumreable 动态和 lambda

    我想在 a 上使用 lambda 表达式IEnumerable
  • C++ 中类级 new 删除运算符的线程安全

    我在我的一门课程中重新实现了新 删除运算符 现在我正在使我的代码成为多线程 并想了解这些运算符是否也需要线程安全 我在某处读到 Visual Studio 中默认的 new delete 运算符是线程安全的 但这对于我的类的自定义 new
  • C++ 标准是否指定了编译器的 STL 实现细节?

    在写答案时this https stackoverflow com questions 30909296 can you put a pimpl class inside a vector我遇到了一个有趣的情况 这个问题演示了这样一种情况

随机推荐

  • (已解决)STM32L151使用串口发送数据第一字节为FE问题!

    已解决 STM32L151使用串口发送数据第一字节为FE问题 参考文章 1 已解决 STM32L151使用串口发送数据第一字节为FE问题 2 https www cnblogs com Irvingcode p 11603583 html
  • 【机器学习】KS值

    KS检验 风控角度 分类模型评判指标 KS曲线与KS值 从统计角度 我们知道KS是分析两组数据分布是否相同的检验指标 在金融领域中 我们的y值和预测得到的违约概率刚好是两个分布未知的两个分布 好的信用风控模型一般从准确性 稳定性和可解释性来
  • Spring创建Bean的全过程(一)

    Spring测试环境搭建 Spring模块概览 Spring中八大模块 黑色表示该模块的jar包 也就是组件 例如我们想要使用IOC容器 也就是绿色的CoreContainer 我们需要导入Beans Core Context SpEL s
  • Python+微信小程序开发实战课

    本套课程Python结合微信小程序开发实战 由前汽车之家架构师武沛齐老师主讲 共分为18天的课程 文件大小共计9G 课程除了讲解微信小程序开发的基础知识点外 更多的是示例演示 让大家知道如何灵活运用这些知识点 真正学到能够运用到具体开发工作
  • Unity3D Shader之路 写Shader前必须要知道的事情3 ShaderForge的简单使用

    版本 unity 5 4 1 语言 Unity Shader Shader Forge版本 1 32 总起 在具体介绍Shader之前准备再写一篇有关于ShaderForge的 虽然我们可能使用代码来直接编写Shader 但拥有Shader
  • python基础——列表推导式

    python基础 列表推导式 文章目录 python基础 列表推导式 一 实验目的 二 实验原理 三 实验环境 四 实验内容 五 实验步骤 一 实验目的 掌握Python数据结构 列表推导式的用法 二 实验原理 列表推导式 list com
  • 「Python 基础」常用模块

    文章目录 1 内建模块 datetime collections namedtuple deque defaultdict OrderedDict ChainMap Counter base64 struct hashlib 摘要算法 摘要
  • Tomcat的基本认识和使用

    服务器 安装了服务器软件的计算机 通常都是高配置的计算机 服务器软件 接收用户的请求 处理请求 做出响应 web服务器软件 通过浏览器来进行访问的一种服务器软件 在web服务器软件中 可以部署web项目 让用户通过浏览器来访问这些项目 常见
  • 常见泰勒展开公式及复杂泰勒展开求法

    目录 https blog csdn net weixin 45792450 article details 104404432 初等的函数泰勒展开 e x e x ex e
  • 【OpenCv】相机标定介绍及python/c++实现

    针孔相机内外参标定简单介绍 之前有一个项目需要公司标内参 之前对这方面没有接触过 网上找了很多资料 记录下相机标定的基础知识 文章是个人浅显理解 如有错误还请指正 非常感谢 参考链接 坐标系转换 相机参数标定 camera calibrat
  • keil4 编译提示 ERROR L107: ADDRESS SPACE OVERFLOW

    单片机型号STC15F2K60s2 编译环境keil4 系统win7 模式 small 错误 ERROR L107 ADDRESS SPACE OVERFLOW 这个错误意思 提示地址超出 又去看了一遍数据手册 不应该是两k吗 为啥用了13
  • 动态链接(一)

    1 为什么要动态链接 静态链接的缺点 1 内存和磁盘空间 比如有两个程序 目标文件分别为Program1 o Program2 o 并且都用到Lib o这个模块 静态链接生成可执行文件Program1 Program2时 它们都分别存有Li
  • 在虚拟机里通过U盘引导安装Win10教程

    一 前言 打算在VM虚拟机里安装一个Win10系统 按照网上的教程 通过虚拟机的光驱加载 iso镜像文件来引导 发现启动不了 虚拟机一直停留在如下界面 推测可能是该 ios镜像文件里没有合适的引导程序 因此 打算尝试U盘启动 经过验证 发现
  • GNS3 FastEthernet1/10 is up, line protocol is down / SVI 无法连接的问题

    请重启三层路由器 三层路由器在打开的情况之下 连接上的设备貌似无法工作
  • K - Robotopia Kattis - robotopia

    题目链接 题解 题目其实类似于以前的解二元一次方程组 但是如果解出方程组后 会得到一个式子 但是如果仅仅代入式子的话是错误的因为假设是这样 5X 6Y 11 5X 6Y 11 这两个方程联立的话很明显是 X 1 Y 1 所以用这种方法不对
  • C语言密勒码的软件编码,密勒码的编码规则是什么?请画出代码序列11010010的密勒码波形?...

    相关题目与解析 CMI码的编码规则是什么 请画出代码序列11010010的CMI码波形 数字双相码的编码规则是什么 请画出代码序列11010010的双相码波形 简述双相码 曼彻斯特码 的编码规则并画出二进制比特序列1011010011的双相
  • k近邻算法的原理、示例与分析

    k近邻算法的原理 示例与分析 代码参考书籍 Python机器学习基础教程 Andreas C muller Sarah Guido著 张亮 译 北京 人民邮电出版社 2018 1 2019 6重印 实现环境 System Ubuntu se
  • Ubuntu查看CPU|GPU|型号等电脑配置

    电脑配置以及CPU 一个终极命令 可以包括以下命令显示的信息 cat proc cpuinfo alay ws sudo dmidecode grep Product Name Product Name Inspiron 3558 Prod
  • matlab以空间的点画球,3D空间画空洞小球Matlab程序

    3D空间画空洞小球Matlab程序 3D空间画空洞小球Matlab程序 有时候在三维空间中 需要画出很多的空洞小球 可以使用入戏的代码 clear all clc x y z sphere 100 hold on i 1 K 3 for c
  • 【C++入门】const和mutable关键字、常函数介绍

    1 常函数介绍 1 1 什么是常函数 1 常函数的定义 类的成员函数对类中任何成员不作修改而只能作访问的函数 简单来说 就是调用类的成员函数不会对类做任何修改 2 常函数的实现 常函数是依靠const关键字实现的 具体是在类中声明成员函数和