当前位置:首页 > 科技  > 软件

C++中的mutable关键字

来源: 责编: 时间:2023-11-20 17:12:37 455观看
导读在C++中mutable关键字正如字面意思所示,表示「可变的」之意。一般在以下两种情况中使用较多,一是修饰类中的变量,用来突破const的限制,二是在Lambda表达式中使用,用来捕获修改表达式之外的变量值。下面我们就针对这两种使

在C++中mutable关键字正如字面意思所示,表示「可变的」之意。一般在以下两种情况中使用较多,一是修饰类中的变量,用来突破const的限制,二是在Lambda表达式中使用,用来捕获修改表达式之外的变量值。0n528资讯网——每日最新资讯28at.com

下面我们就针对这两种使用场景逐个介绍。0n528资讯网——每日最新资讯28at.com

0n528资讯网——每日最新资讯28at.com

mutable修饰类的成员变量

以下实例代码有一个类Person,内部有一个age成员变量表示年龄,有一个被const修饰的公共方法获取年龄:0n528资讯网——每日最新资讯28at.com

#include <iostream>class Person{public:    explicit Person(int a):age(a){    }    ~Person(){    }    int getAge() const{        return age;    }private:    int age{18};};int main() {    const Person person(20);    std::cout << "age = " << person.getAge() << std::endl;    return 0;}

假如我想扩展一下这个类Person的功能,在其内部增加一个counter的字段,用于统计getAge方法的调用次数,于是将其代码改成一下这样子:0n528资讯网——每日最新资讯28at.com

#include <iostream>class Person{public:    explicit Person(int a):age(a){    }    ~Person(){    }    int getAge() const{        counter++;        return age;    }private:    int age{18};    int counter{0};};int main() {    const Person person(20);    std::cout << "age = " << person.getAge() << std::endl;    return 0;}

我们发现代码无法编译通过了,因为getAge函数是被const修饰的,被const修饰的函数,在其内部无法修改该类的成员变量。为了可以让代码通过编译并能顺利运行, 于是我们把第10行和第20行的const去掉即可。0n528资讯网——每日最新资讯28at.com

这个解决方案可以说是正确的,但是同时也在一定程度傻姑娘破坏了我们设计者的本意,因为程序设计者的本意仅仅是希望counter可以被修改,而age还是不能随意修改的, 把const删除后age也可以随意修改了,同时在《Effective C++》一书中作者也提到过一条准则就是只要可能就用 const,明显这个Person也是适合使用const修饰的, 那么我们怎样修改才能做到既使用const保证其他变量不可随意修改,又能保证在const函数体内counter可以修改呢?这时候mutable的关键字的作用就体现出来了。0n528资讯网——每日最新资讯28at.com

我们仅仅需要在声明counter变量时使用mutable修饰一下即可,也就是:0n528资讯网——每日最新资讯28at.com

class Person{public:    explicit Person(int a):age(a){    }    ~Person(){    }    int getAge() const{        counter++;        return age;    }private:    int age{18};    mutable int counter{0};};

同理,如果我们希望在被const修饰的函数getAge内age变量也可被修改的话,也可以使用mutable修饰age变量。0n528资讯网——每日最新资讯28at.com

mutable在Lambda表达式中的作用

C++11标准中引入了 Lambda 表达式,用于定义匿名函数,使得代码更加灵活简洁。0n528资讯网——每日最新资讯28at.com

我们简单回顾一下Lambda表达式的语法,Lambda表达式的语法主要分为五个部分,对应为:0n528资讯网——每日最新资讯28at.com

[捕获列表] (函数参数) mutable 或 exception 声明 -> 返回值类型 {函数体}

其中 mutable 或 exception 声明以及返回值类型是可以忽略不写的。0n528资讯网——每日最新资讯28at.com

捕获列表的值又可以有以下几种形式:0n528资讯网——每日最新资讯28at.com

  • [] 表示不捕获任何变量
  • [=] 表示按值传递的方法捕获父作用域的所有变量
  • [&] 表示按引用传递的方法捕获父作用域的所有变量
  • [=, &a] 表示按值传递的方法捕获父作用域的所有变量,但按引用传递的方法捕获变量a
  • [&, a] 表示按引用传递的方法捕获父作用域的所有变量,但按值传递的方法捕获变量a

其中按值捕获[=]的方式不允许程序员在 Lambda 函数的函数体中修改捕获的变量。而以 mutable 修饰 Lambda 函数,则可以打破这种限制。0n528资讯网——每日最新资讯28at.com

例如一下代码是无法编译通过的:0n528资讯网——每日最新资讯28at.com

#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即可:0n528资讯网——每日最新资讯28at.com

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

在这里考考大家一个简单的问题,为什么在f1内部改变了外部x的值,但是打印x的值还是0呢?为何没有生效呢?0n528资讯网——每日最新资讯28at.com

针对以上例子如果想要在表达式外部修改x的值,笔者觉得直接在捕获列表中使用引用传递不是更加方便明了吗,mutable关键字在Lambda表达式中是否有点脱裤子放屁的感觉?0n528资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-31554-0.htmlC++中的mutable关键字

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: Istio Egress 出口网关使用

下一篇: 家庭影音行业迎来新的重量级选手:多珀 doopoo X3

标签:
  • 热门焦点
  • 鸿蒙OS 4.0公测机型公布:甚至连nova6都支持

    华为全新的HarmonyOS 4.0操作系统将于今天下午正式登场,官方在发布会之前也已经正式给出了可升级的机型产品,这意味着这些机型会率先支持升级享用。这次的HarmonyOS 4.0支持
  • 2023年Q2用户偏好榜:12+256G版本成新主流

    3月份的性能榜、性价比榜和好评榜之后,就要轮到2023年的第二季度偏好榜了,上半年的新机潮已经过去,最明显的肯定就是大内存和存储的机型了,另外部分中端机也取消了屏幕塑料支架
  • JavaScript 混淆及反混淆代码工具

    介绍在我们开始学习反混淆之前,我们首先要了解一下代码混淆。如果不了解代码是如何混淆的,我们可能无法成功对代码进行反混淆,尤其是使用自定义混淆器对其进行混淆时。什么是混
  • 梁柱接棒两年,腾讯音乐闯出新路子

    文丨田静 出品丨牛刀财经(niudaocaijing)7月5日,企鹅FM发布官方公告称由于业务调整,将于9月6日正式停止运营,这意味着腾讯音乐长音频业务走向消亡。腾讯在长音频领域还在摸索。为
  • 得物宠物生意「狂飙」,发力“它经济”

    作者|花花小萌主近日,得物宣布正式上线宠物鉴别,通过得物App内的&ldquo;在线鉴别&rdquo;,可找到鉴别宠物的选项。通过上传自家宠物的部位细节,就能收获拥有专业资质认证的得物鉴
  • 当家的盒马,加速谋生

    来源 | 价值星球Planet作者 | 归去来自己&ldquo;当家&rdquo;的盒马,开始加速谋生了。据盒马官微消息,盒马计划今年开放生鲜供应链,将其生鲜商品送往食堂。目前,盒马在上海已经与
  • 小米MIX Fold 3配置细节曝光:搭载领先版骁龙8 Gen2+罕见5倍长焦

    这段时间以来,包括三星、一加、荣耀等等有不少品牌旗下的最新折叠屏旗舰都得到了不少爆料,而小米新一代折叠屏旗舰——小米MIX Fold 3此前也屡屡被传
  • 华为Mate 60系列用上可变灵动岛:正式版体验将会更出色

    这段时间以来,关于华为新旗舰的爆料日渐密集。据此前多方爆料,今年华为将开始恢复一年双旗舰战略,除上半年推出的P60系列外,往年下半年的Mate系列也将
  • 联想小新Pad Pro 12.6将要推出,搭载高通骁龙 870 处理器

    联想小新Pad Pro 12.6将于秋季新品会上推出,官方按照惯例直接在发布会前给出了机型的所有参数。联想小新 Pad Pro 12.6 将搭载高通骁龙 870 处理器,重量为 5
Top