在 C 中通过值传递还是通过引用到 const 传递更好?

新手上路,请多包涵

在 C++ 中通过值传递还是通过引用传递到 const 更好?

我想知道哪个是更好的做法。我意识到通过引用传递到 const 应该在程序中提供更好的性能,因为您没有制作变量的副本。

原文由 Matt Pascoe 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 637
2 个回答

通常建议最佳实践1 所有类型 使用 pass by const ref,除了内置类型( charintdouble ,等等2。 ),用于迭代器和函数对象(lambdas,派生自 std::*_function 的类)。

移动语义 存在之前尤其如此。原因很简单:如果您按值传递,则必须制作对象的副本,并且除了非常小的对象外,这总是比传递引用更昂贵。

使用 C++11,我们获得了 移动语义。简而言之,移动语义允许在某些情况下,一个对象可以“按值”传递而不复制它。特别是,当您传递的对象是 rvalue 时,就是这种情况。

就其本身而言,移动对象仍然至少与通过引用传递一样昂贵。然而,在许多情况下,一个函数无论如何都会在内部复制一个对象——即它将获得参数的 _所有权_。 2

在这些情况下,我们有以下(简化的)权衡:

  1. 我们可以通过引用传递对象,然后在内部复制。
  2. 我们可以按值传递对象。

“按值传递”仍然会导致对象被复制,除非对象是右值。在右值的情况下,可以移动对象,因此第二种情况突然不再是“复制,然后移动”,而是“移动,然后(可能)再次移动”。

对于实现正确移动构造函数的大型对象(例如向量、字符串……),第二种情况比第 一种 更有效。因此, 如果函数拥有参数的所有权,并且对象类型支持高效移动,则建议使用按值传递


历史注释:

事实上,任何现代编译器都应该能够找出何时按值传递代价高昂,并尽可能隐式地将调用转换为使用 const ref。

理论上。 在实践中,编译器不能总是在不破坏函数的二进制接口的情况下改变它。在某些特殊情况下(当函数被内联时),如果编译器能够确定原始对象不会通过函数中的操作进行更改,则实际上会省略副本。

但总的来说,编译器无法确定这一点,而 C++ 中移动语义的出现使这种优化的相关性大大降低。


1例如,Scott Meyers, Effective C++

2对于对象构造函数来说尤其如此,它可以接受参数并将它们存储在内部,作为构造对象状态的一部分。

原文由 Konrad Rudolph 发布,翻译遵循 CC BY-SA 3.0 许可协议

通过引用传递比通过值传递更好。我正在解决 Leetcode 上最长的公共子序列问题。它显示 TLE 以通过值传递,但接受了代码以通过引用传递。我花了 30 分钟才弄清楚这一点。

原文由 aaa 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题