正确性和硬件写入

时间:2012-10-16 09:57:52

标签: c++ const-correctness

说我有以下成员函数:

void CFoo::regWrite( int addr, int data )
{
  reg_write( addr, data ); // driver call to e.g. write a firmware register
}

显然,调用此函数不会修改调用它的对象的内部状态。但是,它会更改Foo实例代表的任何状态。

在这种情况下,Foo::regWrite(int addr, int data)应该是const函数吗?

4 个答案:

答案 0 :(得分:3)

你必须决定其意义是什么"逻辑const"对于班级CFoo,这取决于班级的用途。

如果CFoo被解释为引用某些数据,则可以通过const CFoo实例修改该数据,在这种情况下,您的成员函数将是const。有关此示例,请考虑引用某些数据的其他类型 - 您可以修改char *constconst std::unique_ptr<char>的参考。

如果CFoo被解释为拥有某些数据,那么通过const CFoo实例禁止修改是有意义的。例如,考虑容器,其中元素在逻辑上是对象状态的一部分&#34;即使它们不是物体的一部分。所以vector::operator[]有一个const重载,返回const T&而不是T&insert成员函数是非常量等等。

答案 1 :(得分:1)

由程序员来定义'const'对于一个类意味着什么。使用说明符mutable,您甚至可以使用const对象来更改成员中的值。当涉及到硬件时,可以将配置视为const正确性的目标:只要配置不改变,对象就可以被认为是常量。

答案 2 :(得分:1)

有两种方法可以看到这一点 - 优化角度和此声明的逻辑。更重要的是你决定。

优化

编辑:我做了一些不正确的假设。看起来编译器实际上不能自由地进行下面的优化,并且只会通过分析方法的 body 来确保它们不会发生修改(即使只是在简单的情况下)。

  

拥有此const将允许编译器优化一点   更多。它知道regWrite不会更改任何字段   对象,如果将它们存储在寄存器中,它可以保留它们   进行依赖于 fields 对象的类似优化   改变。

     

这是编译器在你做的时候唯一依赖的东西   做一个这样的定义,所以有这个const是可以的   理论上可以提供更好的性能。

具有逻辑意义

使用const方法感觉不直观,其目的是破坏性的改变。程序员通常的直觉是,只要我只调用const方法,其他const方法的结果就不应该改变。如果你违反这个不成文的合同,那么人们会感到惊讶 - 即使编译器没问题。

我不确定这是否会被违反 - 这将取决于此课程中的其他代码。但是,如果没有其他考虑因素很重要(性能等),const(对我来说)主要是接口上的标记,表示“调用此对象不会改变此对象的状态”,对于广义定义“国家”。

然而,这是一个阴暗的基础,你认为是一个状态变化取决于你。如果您认为您的固件对象代表内部的链接,则编写寄存器不会改变有关此链接的任何内容,并且是const。如果你认为它代表了底层寄存器的状态,那么写入寄存器就是状态的改变。

答案 3 :(得分:1)

如果你有指向类中其他对象的指针,类似的问题就会出现:你的const方法可以在另一个对象上调用非const方法,从而修改它。

如果您将硬件视为类引用的其他对象,那么修改固件设置将非常有效(因为只更改了“引用”对象)。如果您希望您的班级“代表”硬件(或其中的一部分),我建议不要将该方法标记为const

所以我认为这主要取决于你设计课程的方式。