【深度解析C++】const成员函数

系列文章目录

🌈座右铭🌈:人的一生这么长、你凭什么用短短的几年去衡量自己的一生!

💕个人主页:清灵白羽 漾情天殇_计算机底层原理,深度解析C++,自顶向下看Java-CSDN博客

❤️相关文章❤️:C++this指针:【深度解析C++之this指针】-CSDN博客文章浏览阅读797次,点赞21次,收藏22次。一、为什么需要this指针this指针是C++当中用于指向当前对象的指针,它是成员函数内的一个隐式参数,指向调用该成员函数的对象的内存地址(this指针存放的内容就是对象的内存地址),this指针的主要用途是在成员函数内部访问对象的成员变量和调用其他的成员函数。在类的成员函数当中,如果存在与类的成员变量同名的局部变量或者函数参数,编译器可能无法区分它们,这个时候我们就需要使用this指针可以明确地指出成员变量属于当前对象。https://blog.csdn.net/weixin_59658448/article/details/135136967


目录

系列文章目录

文章目录

前言

一、const成员函数是什么?

1、const成员函数的声明

2、const成员函数的定义

3、const成员函数的特点

        1、不能修改成员变量

        2、只能调用const成员函数

 二、const对象与const成员函数

1、const对象可以调用非const成员函数吗?

2、非const对象可以调用const成员函数吗?

3、const成员函数内可以调用其他非const成员函数吗?

4、非const成员函数内可以调用其他const成员函数吗?

5、总结

三、mutable关键字

1、基本概念

2、使用场景

3、注意事项

 总结


前言

        这篇文章是C++类和对象章节的最后一个知识点,我会结合C++this指针为大家讲解关于C++const成员函数的相关知识以及细节,欢迎大家订阅我的《深度解析C++专栏》能够帮助到大家就是对我最大的鼓励。我会为大家持续输出优质文章。


一、const成员函数是什么?

        在C++中,const成员函数是指在函数声明或定义中使用关键字const修饰的成员函数。这意味着该函数承诺不会修改调用它的对象的成员变量。接下来我为大家详细解释一下。

1、const成员函数的声明

class MyClass {
public:
    void regularFunction();
    void constFunction() const;
};

        在上面的例子中,constFunction 是一个const成员函数。

2、const成员函数的定义

void MyClass::constFunction() const {
    // 在这里只能访问对象的成员变量,但不能修改它们
    // 任何尝试修改成员变量的操作都会导致编译错误
}

3、const成员函数的特点

        1、不能修改成员变量

        在const成员函数中,任何试图修改对象的成员变量的操作都会导致编译错误。这是因为const成员函数语法规定不会修改对象的状态。

        2、只能调用const成员函数

        如果你有一个const对象,你只能调用它的const成员函数。这是因为const对象不允许调用非const成员函数,以防止修改对象的状态。

const MyClass obj;
obj.constFunction(); // 合法
obj.regularFunction(); // 编译错误,因为 regularFunction 不是 const 成员函数

        使用const成员函数的主要目的是为了增强代码的可读性和安全性。通过使用const关键字,我们可以明确表示一个函数不会修改对象的状态,而且编译器也可以进行更严格的检查。


 二、const对象与const成员函数

1、const对象可以调用非const成员函数吗?

        不可以。const对象只能调用const成员函数。调用非const成员函数将导致编译错误,因为这违反了const对象的特性,即不允许修改对象的状态。

2、非const对象可以调用const成员函数吗?

        是的,非const对象可以调用const成员函数。这是因为const成员函数承诺不会修改对象的状态,所以即使是非const对象调用,也不会导致编译错误。

3、const成员函数内可以调用其他非const成员函数吗?

        是的,const成员函数内可以调用其他非const成员函数。因为const成员函数本身不修改对象的状态,而调用非const成员函数的行为并不违反这个承诺。

4、非const成员函数内可以调用其他const成员函数吗?

        是的,非const成员函数内可以调用其他const成员函数。非const成员函数可以修改对象的状态,但它也可以调用不修改状态的const成员函数。这是因为调用const成员函数不会导致破坏对象的const属性。

5、总结

        针对前两个问题为什么const对象只能调用const成员函数呢?因为const成员函数当中的const是用来修饰this指针的,这也就意味着this指针是const类型的,这也就意味着this指针指向的内容不可以发生变化,我们要知道this指针是什么?是一个对象的地址呀!换言之这个this指针指向的内容不可以发生变化也就是这个对象的各种属性都不可以发生变化。

        而对象调用函数的时候编译器会自动地讲这个对象的地址赋值给非静态成员函数的第一个隐式参数,我们认真思考一下,一个非const对象的指针能够赋值给const类型的指针吗?显然是不可以的,非const类型的变量不允许赋值给const类型的变量。这就是为什么只有const对象才能调用const成员函数。这部分的内容涉及到this指针的基本概念,大家如果有不理解的地方可以去看我之前的文章。


三、mutable关键字

        在C++中,mutable关键字用于修饰类的成员变量,允许在const成员函数中修改被mutable修饰的成员变量。这提供了一种例外,允许在const对象上调用const成员函数时修改某些特定的成员变量,而不违反const成员函数的原则。

1、基本概念

class MyClass {
public:
    mutable int counter;  // 使用mutable关键字修饰的成员变量

    void constFunction() const {
        // 在const成员函数中修改被mutable修饰的成员变量
        counter++;
    }
};

2、使用场景

  • 缓存变量的更新: 如果某个成员变量在逻辑上是可以被视为不改变对象状态的,但是为了优化或其他目的,在const成员函数中需要更新,可以使用mutable关键字。

  • 日志记录: 在const成员函数中记录日志的计数或状态信息,而不影响对象的逻辑状态。
    这部分内容的理解还需要我们以后遇到项目的时候具体场景去解决,这篇文章的这部分内容大家理解就好,只需要记住这个关键字是干什么的就行。

3、注意事项

  • mutable关键字只能用于类的非静态成员变量。(因为这个操作没有任何意义,静态成员是属于类的,而成员函数是属于对象的二者不是一个层次的,这样做没有任何意义)

  • 虽然使用mutable允许在const成员函数中修改成员变量,但应该小心确保修改不会导致逻辑错误。

  • 需要慎重使用mutable,因为它破坏了const成员函数的"不修改对象状态"的原则,应该仅在有明确合理的理由时使用。

#include <iostream>

class MyClass {
public:
    mutable int counter;

    void constFunction() const {
        counter++;
        std::cout << "Counter in constFunction: " << counter << std::endl;
    }
};

int main() {
    const MyClass obj;
    obj.constFunction();  // 合法,因为counter是mutable

    return 0;
}

 总结

        const成员函数的主要知识点就为大家全部介绍完毕,C++类和对象的基础知识部分我也全部为大家讲解完成,我用心经营的《深度解析C++》栏目的类和对象专题也到此结束,而此时此刻2023年也终于接近了尾声,这一年太长这一年也太短,这一年的收获很多,虽然辛苦但都是值得的,之后让我们一起迎接崭新的2024。东方欲晓、莫道君行早、踏遍青山人未老、风景这边独好!诸君共勉!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/282074.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Redis技术专区】「原理分析」探讨Redis 6.0为何需要启用多线程?

探讨Redis 6.0为何需要启用多线程 背景介绍开启多线程多线程的CPU核心配置IO多线程模式单线程处理方式多线程处理方式 为什么要开启多线程&#xff1f;充分利用多核CPU提高网络I/O效率响应现代应用需求 多线程实现启用多线程 最后总结 背景介绍 在Redis 6.0版本中&#xff0c;…

期权二叉树估值与图计算

传统期权二叉树的算法都是基于数组的&#xff0c;对于没有编程基础的人来说非常不直观。二叉树是一种特殊的图&#xff0c;可以用python networkx这个图算法库实现&#xff0c;这个库不仅包含常用的图算法&#xff0c;还包含简单的绘图功能&#xff0c;非常适合研究分析使用。 …

git分支场景操作,应用场景

文章目录 git分支操作1.git branch--目前处在的分支上2.git checkout--要切换的分支名字3.git merge--要合并的分支名字4.git branch -d--要删除的分支名字 git分支操作 假设目前我们目前有三个版本 1.git branch–目前处在的分支上 现在要开发一个新功能在新的分支上 新建一…

Python序列之字典

系列文章目录 Python序列之列表Python序列之元组Python序列之字典&#xff08;本篇文章&#xff09;Python序列之集合 Python序列之字典 系列文章目录前言一、字典是什么&#xff1f;二、字典的操作1.创建&#xff08;1&#xff09;通过{}、dict()创建&#xff08;2&#xff0…

Cisco无线Mobility Express配置Image TFTP服务器

思科的无线AP&#xff1a; 1800&#xff0c; 2800&#xff0c; 3800系列 这一类的AP本身可以做为无线控制器使用&#xff0c;被称为Mobility Express&#xff0c;简称为ME 可以管理多少AP 最多可管理 25个 是否需要license才能管理 不需要license 支持哪些型号的AP注册 只要…

Rust学习笔记003:语句和表达式+函数+控制语句:IF,MATCH,LOOP

语句&#xff08;Statements&#xff09;和表达式&#xff08;Expressions&#xff09; 1. 语句&#xff08;Statements&#xff09;&#xff1a; 语句是执行一些操作但不返回值的代码单元。例如&#xff0c;声明变量、赋值、函数调用、宏调用等都是语句。 // 声明变量的语句…

Python教程(19)——python异常处理

异常处理 什么是异常异常处理方式try-except语句捕获异常类型 相关的异常类型 什么是异常 在计算机编程中&#xff0c;异常&#xff08;Exception&#xff09;是指在程序执行过程中发生的错误或异常情况。当出现异常时&#xff0c;程序无法正常继续执行&#xff0c;因此需要采…

【Redis-05】Redis如何实现保存键值对的保存及过期键的管理策略

在之前的文章我们介绍过&#xff0c;Redis服务器在启动之初&#xff0c;会初始化RedisServer的实例&#xff0c;在这个实例中存在很多重要的属性结构&#xff0c;同理本篇博客中介绍的数据库实现原理也会和其中的某些属性相关&#xff0c;我们继续看一下吧。 1.服务器和客户端…

JavaSE语法之十二:Object类

文章目录 一、概念二、获取对象信息三、对象比较equals方法四、hashcode方法 一、概念 Object是Java默认提供的一个类。Java里面除了Object类&#xff0c;所有的类都是存在继承关系的&#xff0c;默认会继承Object父类&#xff0c;即所有的类的对象都可以使用Object的引用进行…

安装与部署Hadoop

一、前置安装准备1、机器2、java3、创建hadoop用户 二、安装Hadoop三、环境配置1、workers2、hadoop-env.sh3、core-site.xml4、hdfs-site.xml5、linux中Hadoop环境变量 四、启动hadoop五、验证 一、前置安装准备 1、机器 主机名ip服务node1192.168.233.100NameNode、DataNod…

纯CSS的华为充电动画,它来了

&#x1f4e2; 鸿蒙专栏&#xff1a;想学鸿蒙的&#xff0c;冲 &#x1f4e2; C语言专栏&#xff1a;想学C语言的&#xff0c;冲 &#x1f4e2; VUE专栏&#xff1a;想学VUE的&#xff0c;冲这里 &#x1f4e2; Krpano专栏&#xff1a;想学Krpano的&#xff0c;冲 &#x1f514…

准备好通过 “Breakin’ B.I.G.” 在嘻哈音乐界大放异彩吧!

在 The Sandbox 推出人物化身系列后&#xff0c;是时候通过 “Breakin’ B.I.G.” 重返嘻哈音乐的黄金时代了。该体验于 12 月 20 日推出&#xff0c;一直持续到 1 月 3 日&#xff0c;让玩家回到 20 世纪 90 年代&#xff0c;体验以 Notorious B.I.G 为主角的 2D 街舞游戏。 获…

【深度学习-目标检测】01 - R-CNN 论文学习与总结

论文地址&#xff1a;Rich feature hierarchies for accurate object detection and semantic segmentation 论文学习 摘要&#xff08;Abstract&#xff09; 对象检测性能的现状&#xff1a; 在PASCAL VOC数据集上测量的对象检测性能在过去几年已经达到了一个高点。最佳性能…

python使用openpyxl为excel模版填充数据,生成多个Sheet页面

目标&#xff1a;希望根据一个给定的excel模版&#xff0c;生成多个Sheet页面&#xff0c;比如模版&#xff1a; 示例程序 import openpyxlexcel_workbook openpyxl.load_workbook("模版.xlsx") for _i in range(3): # 比如填充3个页面# 复制模版sheet页&#x…

arkts状态管理使用(@State、@Prop、@Link、@Provide、@Consume、@objectLink和@observed)

一、状态管理 1.在声明式UI中&#xff0c;是以状态驱动视图更新&#xff1a; ①状态&#xff08;State&#xff09;:指驱动视图更新的数据&#xff08;被装饰器标记的变量&#xff09; ②视图&#xff08;View&#xff09;:基于UI描述渲染得到用户界面 注意&#xff1a; ①…

机场信息集成系统系列介绍(6):机场协同决策支持系统ACDM*续集

目录 1、A-CDM实施效果评估背景 2、评估核心指标项 &#xff08;1&#xff09;机位效率 &#xff08;2&#xff09;登机效率 &#xff08;3&#xff09;推出效率 &#xff08;4&#xff09;滑行效率 &#xff08;5&#xff09;协同效率 3、其他指标项 &#xff08;1&a…

MongoDB Certified Associate Developer 认证考试心得

介绍 前段时间通过了 MongoDB Associate Developer 考试&#xff0c;也记下了一些心得&#xff0c;结果忘记发出来了&#xff0c;现在重新整理下。通过考试后证书是这样的: MongoDB 目前有两个认证证书 1. MongoDB Associate Developer 认证掌握使用MongoDB 来构建现代应用…

kivy开发一个登陆界面

Kivy Kivy是一个用于开发跨平台移动应用&#xff08;如Android和iOS&#xff09;以及桌面应用&#xff08;如Windows、Linux和macOS&#xff09;的Python框架。它采用开源许可证&#xff08;MIT许可证&#xff09;&#xff0c;提供了丰富的图形界面组件和工具&#xff0c;以便…

Tensorflow2.X的GPU版框架最快最稳搭建方法

一、环境基础 Windows10以上 已装Anaconda 支持GPU 二、搭建步骤 1. 在Anaconda中创建并进入虚拟环境 conda create -n envname python3.8 conda activate envname 注意&#xff1a;envname 替换为你自己想命名的&#xff0c;下文将以“Ljdenv”出现 2.安…

二叉树的后序遍历,力扣

目录 建议先刷一下中序遍历 题目地址&#xff1a; 题目&#xff1a; 我们直接看题解吧&#xff1a; 解题方法&#xff1a; 注&#xff1a; 解题分析&#xff1a; 解题思路&#xff1a; 代码实现&#xff1a; 代码实现&#xff08;递归&#xff09;&#xff1a; 代码实现&#x…