想象一个接受int或unsigned int或任何POD的函数签名。 如果您只是从他们那里读取>?
,那么对他们有什么好处吗?我唯一能想到的是,你不会陷入困境并意外地分配给它?
答案 0 :(得分:7)
我假设您正在讨论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-qualifiers是没有意义的。现在在定义中,编译器实际上检查了cv限定符,在这种情况下,它会将参数的更改标记为错误。我看到有些人建议你应该和一些人建议你不要在定义中使用const
来捕捉错误,但在我看到的大多数代码中,const
没有被使用。
答案 1 :(得分:6)
我唯一能想到的是,你不会陷入困境并意外地分配给它?
是的,这是const
的重点。因此,更容易分析和推理函数的目的和正确性。
但是,在公共API const
中制作按值(即非指针/非引用)参数通常被认为是不好的做法:如果您以后想要在实现中修改它们,则需要选择:
- 编辑公共标头以删除const
,这可以触发客户端代码的重新编译(这与文件修改时间戳驱动的make
规则一样),
- 如果你没有从实现中删除const
,你可能会被迫对另一个变量进行低效复制,只是为了能够修改值....
- 允许声明和定义不同,这可能会混淆程序员在两者之间轻弹(如果他们记得在某处看到它,但这不是实现,他们可能会做出被证明是错误的假设 - 同样的危险不存在对于实际上为const
的非const
声明 - 在最坏的情况下,他们会不必要地仔细检查事物,以找出变量的当前状态。)
因此,对于实现文件内部的函数,如果您认为它增加了值,则使用const
(有时详细程度足以让您不再烦恼),但在公共头文件中主动避免它。
在Exceptional C ++中,Herb Sutter建议:
“避免在函数声明中使用const pass-by-value参数。如果不修改参数const仍然在同一函数的定义中。”
答案 2 :(得分:3)
const的正确性应该更多地用于契约,而不是在函数参数中使用时作为优化的工具 它使得使用更直观,并且防止诚实的程序员犯错,除了现代编译器足以胜任应用任何所需的优化。
答案 3 :(得分:1)
让我们澄清一件事:指针有资格作为POD,并且通常的做法是声明它们const
。
作为惯例,整数和浮点参数永远不会被声明为const,即使您的函数无意在其体内更改它们。任何更改都只在函数本身的上下文中,并且永远不会传播回调用者,因此从函数的公共接口的角度来声明它们const
是多余的。
答案 4 :(得分:-1)
无需使用const修饰int或uint参数。
通过这种方式,传递了值:生成此int或uint的副本并将其传递到函数中。在函数中,任何改变都不会影响这个外部int或单元。
将const与指针参数一起使用。