为啥对按值传递的参数使用 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 ) ...
我理解const
在g
中的使用:我们不知道a
在函数外是如何使用的,所以我们要保护它不被修改。但是我不明白在f
中使用const
,其中a
是本地副本。为什么我们需要保护它不被修改?
【问题讨论】:
因为你犯了错误,因为任何阅读它的人都知道它没有被修改。 【参考方案1】:我能想到几个原因:
1) 当有人阅读代码并看到const T a
时,他们知道 a
不应在函数体中进行修改。
2) 当你尝试修改函数体中的a
时,编译器会告诉你。所以添加const
可以防止出错。
顺便说一句,克里斯已经在 cmets 中提到了这一点。
3) 然而,在 C++11 中还有另一个不同之处。不能从常量对象中移动,因为移动操作会修改对象。因此,您只能在函数体中复制a
,不能从中移动。
4) 此外,如果这是类类型,则不能在 const 对象上调用非 const 成员函数。
【讨论】:
能否详细说明第三点?为什么复制构造函数必须可用?我仍然可以move到const
函数参数中,只是我不能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 引用传递的?
当作为参数传递给返回 void 并在函数中修改的函数时,如何修改 Java ArrayList?可能对按值传递感到困惑