为啥对按值传递的参数使用 const? [复制]

Posted

技术标签:

【中文标题】为啥对按值传递的参数使用 const? [复制]【英文标题】:Why using const for arguments passed by value? [duplicate]为什么对按值传递的参数使用 const? [复制] 【发布时间】:2013-09-18 18:53:18 【问题描述】:

假设你有:

int f( const T a )  ... 
int g( const T &a )  ... 

我理解constg中的使用:我们不知道a在函数外是如何使用的,所以我们要保护它不被修改。但是我不明白在f 中使用const,其中a 是本地副本。为什么我们需要保护它不被修改?

【问题讨论】:

因为你犯了错误,因为任何阅读它的人都知道它没有被修改。 【参考方案1】:

我能想到几个原因:

1) 当有人阅读代码并看到const T a 时,他们知道 a 不应在函数体中进行修改。

2) 当你尝试修改函数体中的a 时,编译器会告诉你。所以添加const可以防止出错。

顺便说一句,克里斯已经在 cmets 中提到了这一点。

3) 然而,在 C++11 中还有另一个不同之处。不能从常量对象中移动,因为移动操作会修改对象。因此,您只能在函数体中复制a,不能从中移动。

4) 此外,如果这是类类型,则不能在 const 对象上调用非 const 成员函数。

【讨论】:

能否详细说明第三点?为什么复制构造函数必须可用?我仍然可以moveconst函数参数中,只是我不能moveconst函数参数没有const_cast在函数内部。 为了说明我的观点:ideone.com/ko9Bd2 还是我误解了你? @PetrBudnik:我刚刚更新,我的措辞很差。谢谢。但是,我认为const_cast 如果您尝试使用它,可能会导致未定义的行为。 +1 我认为,我必须同意你的观点,在这种情况下使用 const_cast 会导致 UB。函数参数声明为const,对象确实是常量。感谢您指出这一点。【参考方案2】:

将变量声明为 const 是一种很好的做法。

为什么?

对于按值传递给函数的参数,调用者是否声明const 并不重要。这里的基本原理是在编码时保护自己免受错误,使用编译器警告您正在更改变量的值,以便您可以通过删除 const 修饰符来明确确认此行为。这不仅适用于函数参数,也适用于局部变量。

基于这个理由,我个人总是从声明所有变量 const 开始,并让编译器在我修改它们时发出错误。然后我检查这种行为是否是有意的,如果确实需要,删除const 修饰符。为了更好的易读性,我也总是喜欢以我的变量都是const的方式编码。

【讨论】:

【参考方案3】:

“我个人倾向于不使用 const,除了引用和指针参数。对于复制的对象,这并不重要” 如果您在函数参数中使用 const,则可能是以下原因之一。 1-它帮助编译器优化一些东西。 2-将来没有主体可以修改参数值(如果有很多人在同一个代码库上工作)

【讨论】:

以上是关于为啥对按值传递的参数使用 const? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

为啥向量被视为按值传递,即使它是通过 const 引用传递的?

复制赋值运算符应该通过 const 引用还是按值传递?

当作为参数传递给返回 void 并在函数中修改的函数时,如何修改 Java ArrayList?可能对按值传递感到困惑

python如何决定何时按值传递参数以及何时按引用传递参数? [复制]

Java函数参数是不是总是按值传递数组? [复制]

按值传递时“const”不是多余的吗? [复制]