【深度解析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



前言

        这篇文章是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。东方欲晓、莫道君行早、踏遍青山人未老、风景这边独好!诸君共勉!

相关推荐

最近更新

  1. TCP协议是安全的吗?

    2023-12-31 22:58:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-31 22:58:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-31 22:58:01       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-31 22:58:01       20 阅读

热门阅读

  1. 2023年度总结

    2023-12-31 22:58:01       37 阅读
  2. pycharm配置pyqt5的ui文件转py文件的小工具

    2023-12-31 22:58:01       41 阅读
  3. vue +WebSDK_V3.3.0

    2023-12-31 22:58:01       34 阅读
  4. 什么是Mustache

    2023-12-31 22:58:01       35 阅读
  5. 【MyBatis-Plus】内置接口的使用之CRUD

    2023-12-31 22:58:01       36 阅读
  6. DDD系列 - 第8讲 仓库Repository - JPA篇(二)

    2023-12-31 22:58:01       40 阅读
  7. 接口和抽象类

    2023-12-31 22:58:01       43 阅读
  8. C语言:void*概述(垃圾桶)

    2023-12-31 22:58:01       40 阅读