像其他人所回答的一样,从 API 的角度来看,以下几种方式都是等效的,对于重载解析而言它们是相同的:
void foo( int );
void foo( const int );
但更好的问题是,这是否为使用此API的消费者提供了任何语义意义,或者它是否从实现的开发者中提供了任何良好行为的强制执行?
在没有定义明确的开发人员编码指南的情况下,const标量参数没有明显的语义含义。
对于消费者:
const int不会改变您的输入。它仍然可以是文字,也可以来自另一个变量(无论是const还是非const)。
对于开发人员:
const int对变量(在这种情况下是函数参数)的本地副本施加了限制。这只是意味着要修改参数,您需要获取该变量的另一个副本并对其进行修改。
调用按值接受参数的函数时,在调用的函数栈上制作该参数的副本。这给予该函数在其整个范围内一个参数的本地副本,可随后被修改、用于计算等——而不影响传递到调用中的原始输入。有效地,这提供了其输入的局部变量参数。
通过将参数标记为const,它只是意味着这个副本不能被修改;但它不禁止开发人员复制它并对这个副本进行修改。由于这从一开始就是一个副本,因此它并没有从内部实现方面强制执行太多——从消费者的角度来看,这并没有什么区别。
这与通过引用传递形成对比,其中int&的引用在语义上不同于const int&。前者能够改变其输入;后者只能观察输入(假设实现不会const_cast去掉const);因此,const性对引用具有隐含的语义含义。
它在公共API中并没有提供太多好处;并且(我认为)在实现中引入了不必要的限制。作为任意的、刻意的例子——一个简单的函数如下:
void do_n_times( int n )
{
while( n-- > 0 ) {
}
}
现在必须使用一个不必要的副本来编写代码:
void do_n_times( const int n )
{
auto n_copy = n;
while( n_copy-- > 0 ) {
}
}
无论公共 API 是否使用 const 标量,关键是要在设计中保持一致。如果 API 随机地在使用 const 标量参数和非 const 标量之间切换,则会导致消费者是否存在任何暗示意义的混淆。
简而言之,在公共 API 中使用 const 标量类型不会传达语义意义,除非你为你的域明确定义了自己的指南。
const
是向编译器发出的信号,表明该参数不打算被修改。如果代码试图修改它,那么会发出警告(或错误),因为这与方法/函数的意图相违背。 - Steve