假设我有以下成员函数:
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函数吗?
假设我有以下成员函数:
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函数吗?
CFoo
,“逻辑上的常量”是什么意思,这取决于该类的用途。CFoo
被视为“引用某些数据”,那么可能有意义通过const
实例来修改该数据,在这种情况下,您的成员函数将是const
。例如考虑其他引用某些数据的类型 - 您可以修改char * const
或const std::unique_ptr<char>
的引用对象。CFoo
被视为“拥有某些数据”,则可能有意义禁止通过const
实例来修改该数据。例如考虑容器,其中元素在物理上不属于对象的一部分,但在逻辑上它们是“对象状态的一部分”。因此,vector::operator[]
具有返回const T&
而不是T&
的const重载,insert
成员函数是非const等。对于一个类来说,“const”应该意味着什么由程序员定义。使用修饰符“mutable”,甚至可以在成员中拥有一个具有可变值的“const”对象。当涉及到硬件时,人们可能会将配置视为常量正确性的目标:只要配置不改变,对象就可以被视为常量。
这个问题有两种看法 - 优化角度和声明逻辑。哪一个更重要,由你决定。
编辑:我做了一些错误的假设。似乎编译器实际上不能自由地进行以下优化,只有通过分析方法的主体以确保没有修改发生(即使在简单情况下也是如此)才会进行这些优化。
拥有这个
const
将允许编译器进行一些优化。它知道regWrite
不会改变对象中的任何字段,因此如果它正在存储它们,则可以保留它们,并进行依赖于对象字段未被更改的类似优化。当您制作这样的定义时,这真的是编译器所依赖的唯一事情,因此拥有这个
const
是可以的,并且理论上可以提高性能。
在一个const
方法中进行破坏性的改变感觉不直观。程序员通常的直觉是只要我调用的是const方法,其他const
方法的结果就不应该改变。如果你违反了这个不成文的契约,即使编译器没有问题,人们也会感到惊讶。
我不确定这里是否会违反这个契约 - 这将取决于这个类中的其他代码。然而,如果没有其他考虑因素(性能等),对于我来说,const
主要是接口上的一个标记,表示“调用此方法不会改变此对象的状态”,对于“状态”的广义定义而言。
然而,这是模糊的领域,你可以自行决定什么是状态改变。如果你认为你的固件对象代表着内部的一个链接,那么写入寄存器并不会改变这个链接的任何内容,因此是const的。如果你认为它代表底层寄存器的状态,那么写入寄存器就是一种状态改变。
const
。
CFoo
类是否代表固件?(例如,固件状态是否可以视为对象状态?) - Krumelur