每当您在逻辑上不更改值或对象时,您都应该进行更改const
。从逻辑上讲,我并不是指每次在技术上都允许这样做,而是每次在函数、类和代码的上下文中都是合乎逻辑的。
一个简单的示例可以是示例 1 中所示的简单“get”函数,这些函数不应修改类的状态,因此应标记为常量,因为这将有助于向用户记录您的意图,同时帮助您确保类的不变性。
在某些情况下,创建不可变对象是有意义的,如示例 2 所示。我们在 C++ 中并不经常看到这些,但许多其他语言经常使用它们。如果它没有添加任何值以能够在对象生命周期内更改某个成员,那么您不妨将其设为 const。
传递 const 引用参数可以为您提供引用的性能优势,但同时确保源对象保持不变,这对用户来说既是很好的文档,也允许进行 som 优化。
提到了所有这些原因,还有其他原因可以使用const
,如上一段中简要提到的,优化。当编译器知道某些东西是不变的并且没有被改变时,它可以启用一些非常聪明的优化,但不要const
出于性能原因使用。
这也是为什么通过(例如)const_cast
可以抛弃的演员来解决 constnessconst
会导致一些不良行为的原因。例如,检查以下内容:
#include <stdio.h>
static const int foo = 10;
int constsum(void) {
return foo + 5;
}
int main(int argc, char* argv[]) {
int a = constsum();
int* newFoo = const_cast<int*>(&foo);
*newFoo = 20;
int b = constsum();
printf("%d\n", a + b);
return 0;
}
从这个例子中可以看出(见这里运行的代码),这可能不会产生预期的结果,因为代码会30
被打印出来,而不是预期的 40。
在检查生成的程序集时,我们可以看到原因(编译成程序集):
constsum():
mov eax, 15
ret
main:
mov eax, 30
ret
编译器只是内联值,因为它可以看到它们是常量,它并不特别注意const_cast
正在使用的值。
所以 const 正确性和使用const
是一个有价值的工具,它可以提高代码的性能和稳定性,而且(不要忘记)它有助于记录你的代码。