const 成员函数的语义是什么?

2024-05-23

我知道该函数不允许更改对象的状态,但我想我在某处读到允许编译器假设如果使用相同的参数调用该函数,它将返回相同的值,因此可以重用缓存值(如果可用)。例如

class object
{
    int get_value(int n) const
    {
        ...
    }

...


object x;

int a = x.get_value(1);
    ...
int b = x.get_value(1);

那么编译器可以优化第二个调用并使用寄存器中的值或简单地执行b = a;

这是真的?


const是关于程序语义而不是实现细节。你应该标记一个成员函数const当它不改变对象的可见状态时,并且应该可以在本身的对象上调用const。在一个const类的成员函数X,类型this is X const *: 指向常量的指针X目的。因此所有成员变量都是有效的const在该成员函数内(除了mutable那些)。如果你有一个const对象,只能调用const其上的成员函数。

您可以使用mutable表明成员变量甚至可以在一个const成员函数。这通常用于标识用于缓存结果的变量,或者用于不影响实际可观察​​状态的变量,例如互斥体(您仍然需要将互斥体锁定在const成员函数)或使用计数器。

class X
{
    int data;
    mutable boost::mutex m;
public:
    void set_data(int i)
    {
        boost::lock_guard<boost::mutex> lk(m);
        data=i;
    }
    int get_data() const // we want to be able to get the data on a const object
    {
        boost::lock_guard<boost::mutex> lk(m); // this requires m to be non-const
        return data;
    }
};

如果您通过指针而不是直接保存数据(包括智能指针,例如std::auto_ptr or boost::shared_ptr) 那么指针就变成const in a const成员函数,但不是指向的数据,因此可以修改指向的数据。

至于缓存:一般来说,编译器无法执行此操作,因为状态可能会在调用之间发生变化(特别是在我使用互斥锁的多线程示例中)。但是,如果定义是内联的,则编译器可以将代码拉入调用函数并优化在那里看到的内容。这可能会导致函数有效地只被调用一次。

下一个版本的C++ 标准 (C++0x) http://www.open-std.org/jtc1/sc22/wg21/将有一个新的关键字constexpr。功能标记constexpr返回一个常量值,因此可以缓存结果。在这样的函数中可以执行的操作是有限的(以便编译器可以验证这一事实)。

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

const 成员函数的语义是什么? 的相关文章

  • C 编程 - 文件 - fwrite

    我有一个关于编程和文件的问题 while current NULL if current gt Id Doctor 0 current current gt next id doc current gt Id Doctor if curre
  • “构建”构建我的项目,“构建解决方案”则不构建

    我刚刚开始使用VS2010 我有一个较大的解决方案 已从 VS2008 成功迁移 我已将一个名为 Test 的控制台应用程序项目添加到解决方案中 选择构建 gt 构建解决方案不编译新项目 选择构建 gt 构建测试确实构建了项目 在失败的情况
  • 以文化中立的方式将字符串拆分为单词

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

    我正在尝试将模块动态加载到我的应用程序中 但我想为每个模块指定单独的 app config 文件 假设我的主应用程序有以下 app config 设置
  • 秒表有最长运行时间吗?

    多久可以Stopwatch在 NET 中运行 如果达到该限制 它会回绕到负数还是从 0 重新开始 Stopwatch Elapsed返回一个TimeSpan From MSDN https learn microsoft com en us
  • 不支持将数据直接绑定到存储查询(DbSet、DbQuery、DbSqlQuery)

    正在编码视觉工作室2012并使用实体模型作为我的数据层 但是 当页面尝试加载时 上面提到的标题 我使用 Linq 语句的下拉控件往往会引发未处理的异常 下面是我的代码 using AdventureWorksEntities dw new
  • PHP 接口有属性吗?

    PHP 中的接口有属性 还是只有方法 您可以在 DocBlock 中为接口声明属性 然后 IDE 将提示接口的这些属性 PhpStorm 会这样做 但这不会强制在实现类中实际实现这些字段 例如 property string passwor
  • 为什么当实例化新的游戏对象时,它没有向它们添加标签? [复制]

    这个问题在这里已经有答案了 using System Collections using System Collections Generic using UnityEngine public class Test MonoBehaviou
  • 嵌套接口:将 IDictionary> 转换为 IDictionary>?

    我认为投射一个相当简单IDictionary
  • BitTorrent 追踪器宣布问题

    我花了一点业余时间编写 BitTorrent 客户端 主要是出于好奇 但部分是出于提高我的 C 技能的愿望 我一直在使用理论维基 http wiki theory org BitTorrentSpecification作为我的向导 我已经建
  • 在 ASP.NET 5 中使用 DI 调用构造函数时解决依赖关系

    Web 上似乎充斥着如何在 ASP NET 5 中使用 DI 的示例 但没有一个示例显示如何调用构造函数并解决依赖关系 以下只是众多案例之一 http social technet microsoft com wiki contents a
  • 带动态元素的 WPF 启动屏幕。如何?

    我是 WPF 新手 我需要一些帮助 我有一个加载缓慢的 WPF 应用程序 因此我显示启动屏幕作为权宜之计 但是 我希望能够在每次运行时更改屏幕 并在文本区域中显示不同的引言 这是一个生产力应用程序 所以我将使用非愚蠢但激励性的引言 当然 如
  • 将多个表映射到实体框架中的单个实体类

    我正在开发一个旧数据库 该数据库有 2 个具有 1 1 关系的表 目前 我为每个定义的表定义了一种类型 1Test 1Result 我想将这些特定的表合并到一个类中 当前的类型如下所示 public class Result public
  • 如何在 C 中调用采用匿名结构的函数?

    如何在 C 中调用采用匿名结构的函数 比如这个函数 void func struct int x p printf i n p x 当提供原型的函数声明在范围内时 调用该函数的参数必须具有与原型中声明的类型兼容的类型 其中 兼容 具有标准定
  • 覆盖子类中的字段或属性

    我有一个抽象基类 我想声明一个字段或属性 该字段或属性在从该父类继承的每个类中具有不同的值 我想在基类中定义它 以便我可以在基类方法中引用它 例如覆盖 ToString 来表示 此对象的类型为 property field 我有三种方法可以
  • cmake 将标头包含到每个源文件中

    其实我有一个简单的问题 但找不到答案 也许你可以给我指一个副本 所以 问题是 是否可以告诉 cmake 指示编译器在每个源文件的开头自动包含一些头文件 这样就不需要放置 include foo h 了 谢谢 CMake 没有针对此特定用例的
  • 将控制台重定向到 .NET 程序中的字符串

    如何重定向写入控制台的任何内容以写入字符串 对于您自己的流程 Console SetOut http msdn microsoft com en us library system console setout aspx并将其重定向到构建在
  • C# - OutOfMemoryException 在 JSON 文件上保存列表

    我正在尝试保存压力图的流数据 基本上我有一个压力矩阵定义为 double pressureMatrix new double e Data GetLength 0 e Data GetLength 1 基本上 我得到了其中之一pressur
  • C++ 中类级 new 删除运算符的线程安全

    我在我的一门课程中重新实现了新 删除运算符 现在我正在使我的代码成为多线程 并想了解这些运算符是否也需要线程安全 我在某处读到 Visual Studio 中默认的 new delete 运算符是线程安全的 但这对于我的类的自定义 new
  • 如何防止用户控件表单在 C# 中处理键盘输入(箭头键)

    我的用户控件包含其他可以选择的控件 我想实现使用箭头键导航子控件的方法 问题是家长控制拦截箭头键并使用它来滚动其视图什么是我想避免的事情 我想自己解决控制内容的导航问题 我如何控制由箭头键引起的标准行为 提前致谢 MTH 这通常是通过重写

随机推荐

  • 更高效的 LINQ 查询

    有人可以帮我将此查询循环变成高效的 Linq 查询吗 我将其加载到 TreeView 中 因此必须附加每个项目 包含也非常低效 延迟加载项目也不起作用 事实上 这个查询访问数据库的次数比应有的要多 public IQueryable
  • 禁用外部点击时关闭模式

    我正在制作一些使用模式的博客物质化 但我的模态 onclick 外部和错误数据有问题 这是我的代码 main js function changepassword var user userlog val var content conte
  • 致命错误:在 flutter 中找不到“Flutter/Flutter.h”文件

    这是错误 在文件中包含来自 Users chetan pub cache hosted pub dartlang org webview flutter 1 0 7 ios Classes JavaScriptChannelHandler
  • LLVM 互操作性(如 JVM 或 .Net)- 可以吗?

    我最近尝试了一些不同的 LLVM 前端 例如 Clang C Familiy LDC2 D Terra 所有这些语言都可以编译成 LLVM IR 有点可读 和 LLVM IR Bitcode 那么现阶段他们都处于同一 水平 对吗 我的问题是
  • 将值设置为输入字段时,西班牙语文本无法正确显示

    我正在尝试将西班牙语文本设置到输入字段 但它似乎没有正确显示 但是 如果相同的文本位于 div 内部或已设置为输入字段的值 则该文本可以正常显示 HTML div Cuenta de Ahorros Persona F iacute sic
  • 不同类型的 C++ 对称二元运算符

    我正在学习 C 我想知道是否可以深入了解创建适用于两种不同类型实例的二元运算符的首选方法 这是我为了说明我的担忧而制作的一个例子 class A class B class A private int x public A int x in
  • golang.org 包和标准库之间的区别

    我使用 go 已经有一段时间了 我注意到 Go 标准库 和 golang org x 之间存在重复的包 我的问题是 为什么它们被释放两次 在这两者中 我应该使用哪一个 更新的 规范的等 到目前为止我注意到的一些示例包已发布两次 golang
  • Flask 或 Pyramid 中的简单网络 UDP 监听

    我需要创建一个 Web 应用程序来显示通过定期传入 UDP 数据包提供的数据 该站点可能位于 Flask 可能是 Pyramid 中 部署在 Nginx 下 如何创建一个非常简单的后台任务 基本上只是 socket recv 来侦听任何传入
  • 使用 iostream << 序列化用户对象

    我想使用运算符 ofstream out file ios out ios binary int i 0xAA out lt lt i 并输出 0x31 0x37 0x30 即 0xAA gt 170 170 如果我使用 write 函数
  • 从所有动态生成的控件中获取文本总和

    我有一个 Windows 窗体 其中有下面列出的控件面板1 按钮1 添加新手机 按钮2 确定单击button1 时会添加一个用户控件 您可以根据需要添加任意数量的用户控件 userControl 定义由五个控件组成 组合框1 组合框2 文本
  • 在requirements.txt中包含.whl安装

    如何将其包含在requirements txt 文件中 对于Linux pip install http download pytorch org whl cu75 torch 0 1 12 post2 cp27 none linux x8
  • 正则表达式在 R 中同时多次包含字母/特殊字符时删除单词

    我想删除那些单词中字母 特殊字符的数量同时出现两次以上的单词 例如 输入就像 Google in theee lland of whhhat c c and e 输出应该是 Google in lland of c c and x lt G
  • 如何调用 window.alert("message");来自 C#?

    根据某些条件 我有自己的异常 并且希望在控制进入此 catch 块时发出警报 catch ApplicationException ex want to call window alert function here 你是说消息框吗 Mes
  • 使用 Maven 外部化 SCM 凭证

    有没有一种方法可以外部化我的 SCM 凭据 以便它们不会存储在项目的 POM 中 问题是 如果它们包含在项目的 POM 中 那么在部署项目时它们将对所有人可见 对于某些 SCM 提供商 您可以在
  • Postgres 从 10 升级到 12:pg_upgrade 由于存在所需库而失败

    usr pgsql 12 bin pg upgrade gt b usr pgsql 1 pgsql 10 pgsql 12 gt b usr pgsql 10 bin gt B usr pgsql 12 bin gt d var lib
  • 如何将功能标志“传递”到 Cargo 中的子依赖项?

    我正在 Cargo 中编写一个库 如果这个库依赖于另一个库 例如libc http crates io crates libc 它公开了一个功能 在本例中 use std 如何使我公开的功能在我的依赖项中启用或禁用该功能 看着货物文件 ht
  • 如何查看 Chrome 开发者工具网络选项卡中使用的协议?

    Chrome 开发人员工具栏上的网络选项卡很棒 但我想看看使用什么协议来传输资源 HTTP 或 HTTPS 任何人都知道我该怎么做 或者是否有扩展允许我做类似的事情 好吧 现在是 2016 年了 现在您可以在 chrome 开发工具中拥有一
  • JavaScript CSV 验证

    如何检查文本框中的逗号分隔值并在未找到时发出警报 如果有的话 里面应该有字符 比如A B C D function validate validate text box
  • Angular 2 从 styles.scss 扩展样式

    在 Angular 2 中 我的 CSS 类styles scss file FirstClass 我试图在组件的 SCSS 文件中扩展此类 例如 MyComponent scss like SecondClass extend First
  • const 成员函数的语义是什么?

    我知道该函数不允许更改对象的状态 但我想我在某处读到允许编译器假设如果使用相同的参数调用该函数 它将返回相同的值 因此可以重用缓存值 如果可用 例如 class object int get value int n const object