想象一个接受 int 或 unsigned int 或任何 POD 的函数签名。如果您只是阅读它们,那么 const 它们有什么好处>?
我能想到的唯一一个,是让你不要搞砸并意外分配给它?
我假设您在谈论顶级限定符void f( const type x )
,而不是指向/引用对象的 const 。在这种情况下,重要的是要注意,语言确定函数参数中的顶级 const-volatile 限定符从函数的签名中删除,即以下声明相同的函数:
void f( int );
void f( const int );
void f( volatile int );
void f( const volatile int );
从这个角度来看,在声明中添加 cv 限定符是没有意义的。现在在定义中,编译器实际上检查了 cv 限定符,在这种情况下,它会将对参数的更改标记为错误。我见过一些人建议你应该和一些人建议你不应该const
在定义中使用来捕捉错误,但在我见过的大多数代码中,const
并没有使用。
我能想到的唯一一个,是让你不要搞砸并意外分配给它?
是的,这就是const
. 因此,更容易分析和推理函数的目的和正确性。
尽管如此,在公共 API 中使用按值(即非指针/非引用)参数通常被认为是不好的做法const
:如果您稍后想在实现中修改它们,您需要在以下选项之间进行选择: - 编辑公共标头to remove const
,这可能会触发客户端代码的重新编译(这在文件修改时间戳驱动的make
规则中很常见), - 如果您不const
从实现中删除 ,您可能会被迫对另一个变量进行低效复制,以便能够修改值.... - 允许声明和定义不同,这可能会使程序员在两者之间摇摆不定(如果他们记得在某处看到它 const 但那不是实现,他们可能会做出证明是错误的假设- 同样的危险不会't 存在于非const
实际上是声明const
- 最坏的情况是他们不必要地仔细检查事物以找出变量的当前状态)。
因此,对于实现文件内部的函数,const
如果您认为它增加了价值,请使用(有时冗长足以让您不打扰),但在公共头文件中积极避免使用它。
在 Exceptional C++ 中,Herb Sutter 建议:
“避免在函数声明中使用 const 传值参数。如果不修改,仍然在同一函数的定义中使用 const 参数。”
const 正确性应该更多地用于合同,而不是在函数参数中使用时作为优化工具。
它使使用更直观,并防止诚实的程序员犯错误,除了现代编译器足以应用任何所需的优化。
让我们澄清一件事:指针符合 POD 的条件,通常的做法是声明它们const
。
按照惯例,整数和浮点参数永远不会声明为 const,即使您的函数无意在其主体内更改它们。任何更改都只在函数本身的上下文中,并且永远不会传播回调用者,因此从函数的公共接口的角度来看,声明它们const
是多余的。
无需用 const 装饰 int 或 uint 参数。
这样,值就被传递了:这个 int 或 uint 的副本被生成并传递到你的函数中。在函数内,任何更改都不会影响这个外部 int 或单元。
将 const 与指针参数一起使用。