C++中的mutable关键字详解

2024-09-08 05:04
文章标签 c++ 详解 关键字 mutable

本文主要是介绍C++中的mutable关键字详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

1.概述

2.使用场景

3.示例

4.mutable修饰Lambda表达式

5.注意事项


1.概述

        在C++中,mutable也是为了突破const的限制而设置的。被mutable修饰的变量,将永远处于可变的状态,即使在一个const函数中。

        我们知道,被const关键字修饰的函数的一个重要作用就是为了能够保护类中的成员变量。即:该函数可以使用类中的所有成员变量,但是不能修改他们的值。

        然而,在某些特殊情况下,我们还是需要在const函数中修改类的某些成员变量,因为要修改的成员变量与类本身并无多少关系,即使修改了也不会对类造成多少影响。当然,你可以说,你可以去掉该函数的const关键字呀!但问题是,我只想修改某个成员变量,其余成员变量仍然希望被const保护。

2.使用场景

  mutable成员通常用于需要记录状态但又不影响对象逻辑上不可变性的场景。一个常见的例子是使用mutable来修饰记录缓存数据的成员变量,或者是在多线程环境中记录访问次数的成员变量。

3.示例

        假设我们有一个类,它代表一个可以被读取但不能被直接修改的数据库记录。但我们希望在每次访问这个记录时更新一个访问计数器,我们可以使用mutable来实现这个需求:

#include <iostream>  class DatabaseRecord {  
private:  int data;  // 假设这是从数据库中读取的数据  mutable int accessCount;  // 访问计数器,使用mutable修饰  public:  DatabaseRecord(int d) : data(d), accessCount(0) {}  // const成员函数,但允许修改mutable成员  void display() const {  ++accessCount;  // 修改mutable成员是允许的  std::cout << "Data: " << data << ", Accessed " << accessCount << " times." << std::endl;  }  // 假设还有其他成员函数...  
};  int main() {  const DatabaseRecord record(42);  // 创建一个const对象  record.display();  // 调用const成员函数,同时修改mutable成员  record.display();  // 再次调用,显示访问次数增加  return 0;  
}

4.mutable修饰Lambda表达式

       C++11 引入了 Lambda 表达式,程序员可以凭此创建匿名函数。在 Lambda 表达式的设计中,捕获变量有几种方式;其中按值捕获(Caputre by Value)的方式不允许程序员在 Lambda 函数的函数体中修改捕获的变量。而以 mutable 修饰 Lambda 函数,则可以打破这种限制。

        例如一下代码是无法编译通过的:

#include  <iostream>int  main()
{int x{0};auto f1 = [=]() {return ++x;}; f1();std::cout << "x =" << x << std::endl:return 0;
}

        因为Lambda表达式f1,在内部修改了表达式外部x的值,但是又没有使用mutable关键字声明,此时我们只需要使用mutable关键字声明一下f1即可:

#include  <iostream>int  main()
{int x{0};auto f1 = [=]() mutable {return ++x;}; f1();std::cout << "x = " << x << std::endl:return 0;
}

        需要注意的是,上述 f1 的函数体中,虽然我们给 x 做了赋值操作,但是这一操作仅只在函数内部生效——即,实际是给拷贝至函数内部的 x 进行赋值——而外部的 x 的值依旧是 0

5.注意事项

  • 使用mutable时应当谨慎,因为它可能会隐藏类的实际不可变性,使得代码的阅读和维护变得更加困难。
  • mutable只能用于类的成员变量,不能用于成员函数或类型本身。
  • 即使在const成员函数中,mutable成员也可以被修改,但这并不意味着你可以修改类的其他非mutable成员。尝试这样做会导致编译错误。
  • mutable不会影响成员变量的存储方式或性能,它只是改变了编译器的检查规则。
  • mutable不能修饰const 和 static 类型的变量。

这篇关于C++中的mutable关键字详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1147189

相关文章

java图像识别工具类(ImageRecognitionUtils)使用实例详解

《java图像识别工具类(ImageRecognitionUtils)使用实例详解》:本文主要介绍如何在Java中使用OpenCV进行图像识别,包括图像加载、预处理、分类、人脸检测和特征提取等步骤... 目录前言1. 图像识别的背景与作用2. 设计目标3. 项目依赖4. 设计与实现 ImageRecogni

Java访问修饰符public、private、protected及默认访问权限详解

《Java访问修饰符public、private、protected及默认访问权限详解》:本文主要介绍Java访问修饰符public、private、protected及默认访问权限的相关资料,每... 目录前言1. public 访问修饰符特点:示例:适用场景:2. private 访问修饰符特点:示例:

python管理工具之conda安装部署及使用详解

《python管理工具之conda安装部署及使用详解》这篇文章详细介绍了如何安装和使用conda来管理Python环境,它涵盖了从安装部署、镜像源配置到具体的conda使用方法,包括创建、激活、安装包... 目录pytpshheraerUhon管理工具:conda部署+使用一、安装部署1、 下载2、 安装3

详解Java如何向http/https接口发出请求

《详解Java如何向http/https接口发出请求》这篇文章主要为大家详细介绍了Java如何实现向http/https接口发出请求,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 用Java发送web请求所用到的包都在java.net下,在具体使用时可以用如下代码,你可以把它封装成一

JAVA系统中Spring Boot应用程序的配置文件application.yml使用详解

《JAVA系统中SpringBoot应用程序的配置文件application.yml使用详解》:本文主要介绍JAVA系统中SpringBoot应用程序的配置文件application.yml的... 目录文件路径文件内容解释1. Server 配置2. Spring 配置3. Logging 配置4. Ma

C#使用yield关键字实现提升迭代性能与效率

《C#使用yield关键字实现提升迭代性能与效率》yield关键字在C#中简化了数据迭代的方式,实现了按需生成数据,自动维护迭代状态,本文主要来聊聊如何使用yield关键字实现提升迭代性能与效率,感兴... 目录前言传统迭代和yield迭代方式对比yield延迟加载按需获取数据yield break显式示迭

c# checked和unchecked关键字的使用

《c#checked和unchecked关键字的使用》C#中的checked关键字用于启用整数运算的溢出检查,可以捕获并抛出System.OverflowException异常,而unchecked... 目录在 C# 中,checked 关键字用于启用整数运算的溢出检查。默认情况下,C# 的整数运算不会自

mac中资源库在哪? macOS资源库文件夹详解

《mac中资源库在哪?macOS资源库文件夹详解》经常使用Mac电脑的用户会发现,找不到Mac电脑的资源库,我们怎么打开资源库并使用呢?下面我们就来看看macOS资源库文件夹详解... 在 MACOS 系统中,「资源库」文件夹是用来存放操作系统和 App 设置的核心位置。虽然平时我们很少直接跟它打交道,但了

关于Maven中pom.xml文件配置详解

《关于Maven中pom.xml文件配置详解》pom.xml是Maven项目的核心配置文件,它描述了项目的结构、依赖关系、构建配置等信息,通过合理配置pom.xml,可以提高项目的可维护性和构建效率... 目录1. POM文件的基本结构1.1 项目基本信息2. 项目属性2.1 引用属性3. 项目依赖4. 构

Rust 数据类型详解

《Rust数据类型详解》本文介绍了Rust编程语言中的标量类型和复合类型,标量类型包括整数、浮点数、布尔和字符,而复合类型则包括元组和数组,标量类型用于表示单个值,具有不同的表示和范围,本文介绍的非... 目录一、标量类型(Scalar Types)1. 整数类型(Integer Types)1.1 整数字