【问题标题】:when to pass by reference and when by value in c / c++ [duplicate]在c / c ++中何时通过引用传递以及何时通过值传递[重复]
【发布时间】:2023-04-09 16:04:01
【问题描述】:

可能重复:
Is it better in C++ to pass by value or pass by constant reference?
When to pass by reference and when to pass by pointer in C++?

我对 c 和 c++ 还很陌生,关于将参数传递给函数,我有以下问题,我认为最好在这里提问,直接从专家那里获得知识的来源。

什么时候应该按值传递参数,什么时候应该按引用传递?而现实世界中最常用的方法是什么?

提前致谢。

【问题讨论】:

  • C 没有引用。因此我删除了 C 标签。
  • 相关列表中有很多关于这个主题的问题----->
  • 显然 不是 所提议的骗子的副本(尽管我确定存在一个)
  • 不是与“by pointers vs by reference”问题的重复。除非有真正的重复,否则请不要关闭它。
  • 这是一个更好的副本:stackoverflow.com/questions/270408/…

标签: c++ parameters pass-by-reference pass-by-value


【解决方案1】:

首选通过引用传递,通常是以下一项或多项:

  1. 如果它很大。 (如果是const,一定要这样做,不过还是要经常这样做,具体取决于此列表的其余部分)
  2. 如果您想对其进行编辑并使更改全局可见。
  3. 如果您希望虚函数具有多态行为。
  4. 如果您不知道它将是什么类型,请在模板代码中。

按值传递:

  1. 如果它是一个普通的内置类型(例如 int)
  2. 如果您不想更改原始对象。
  3. 如果您希望能够传递临时变量而不必将其设为 const。

【讨论】:

  • 现在更好地澄清了const 点。
  • “使更改全局可见”有点牵强附会;您的对象可能没有全局可见的属性。
  • @Tomalak:“函数外可见的变化”怎么样?
  • 如果函数每天只调用一次,则无需通过引用传递大对象。
  • @John:也就是说,如果你可以处理 pass-by-reference-to-const ,那么即使它每天只调用一次,你也应该 - 明天它可能会被调用数百万次一天。
【解决方案2】:

如果参数大于 register 并且你没有修改它,你应该将它作为 const 引用传递。当然,也有一些例外情况,您稍后会创建一个副本,但总的来说,这条规则是正确的。

对于较小的类型,没有关系(即 const int& 或 int)应该给出相同的结果。为了安全起见,无论如何都要按值传递它们。对于通用代码,您可以使用Boost Call Traits 库,它会自动决定是使用引用还是按值。

如果你想修改对象,将它作为引用传入允许你就地修改它,这通常比返回一个新对象并覆盖原来的对象要快。

【讨论】:

  • 鉴于 C++ 没有定义寄存器的大小,我不明白应该如何进行这样的调用。 (而且在许多架构上,例如 x86,寄存器不用于传递参数)
  • 原始类型是寄存器大小的,适用于最常见的平台。标准 ABI 通常还会将一些参数打包到寄存器中,x64 更是如此。
  • 这接近于过早的微优化。
  • Hu?`传递 int/float/double/etc.作为价值,所有更大的东西作为 const 参考&闻起来不像“微优化”,而是作为一个很好的一般经验法则。
  • @Anteru:Linux/BSD/大多数 posix box (cdecl) 和 Windows (stdcall) 使用的标准 ABI 都不使用寄存器来传递参数。
【解决方案3】:

默认情况下,通过 const 引用传递,除了:

1) 如果你想要一个 in/out 或 out 参数 - 一个被函数改变的参数。在这种情况下,请使用非常量引用。 2) 如果您传递的是整数、浮点数或指针 - 按值传递。

【讨论】:

  • 或 3 -- 您需要更改参数并且不希望该更改对客户端可见。
【解决方案4】:

通常,当您需要更改参数并且不希望调用者必须进行复制时,您应该使用按值传递。您应该在其他任何地方都使用对 const 的引用传递。

但是,这实际上归结为“C++ 作为语言的联合”位——例如,如果您正在编写 STL 算法,则需要使用按值传递,因为迭代器和仿函数近似于指针和函数指针。

【讨论】:

    【解决方案5】:

    除其他外,这主要取决于您的需求。如果您想看到对传递的变量所做的更改反映在当前函数中,您肯定会通过引用传递,但如果您严格要求所做的任何更改传递的变量不会反映在您当前的函数中 go for 'passed by value'。

    谢谢, 马维亚

    【讨论】:

      【解决方案6】:

      按价值传递,除非你有理由不这样做。不这样做的原因:

      1. 您希望函数以某种方式更改对象。通过引用或指针传递。
      2. 对象是“大”。 “大”的精确定义将取决于您的计算机、您的平台、复制对象的后果等。您必须根据具体情况进行评估。通过 const 引用传递。
      3. 复制对象会做一些“坏事”。例如,如果通过复制文件指针对象会创建另一个文件,或者通过复制同步对象会创建死锁。通过 const 引用传递。
      4. 您需要传入对象的多态行为。通过引用或指针传递。按值传递将slice the object

      请注意,对于上面的#2,即使对象很大,您仍可能希望按值传递。按值传递更简单因此更易于维护,除非您有理由相信按值传递会在代码中产生实际问题,否则按 const 引用传递可能是过早的微优化。例如,如果您的函数采用一个 64 字节(甚至 64k 字节)的参数,但该函数每天只调用一次,则实际上没有理由通过 const 引用传递。它几乎不会为您节省任何费用。首先在发布模式下分析您的代码,然后进行优化。

      【讨论】:

        猜你喜欢
        • 2011-04-06
        • 2012-03-30
        • 2020-04-01
        • 1970-01-01
        • 2014-07-05
        • 1970-01-01
        相关资源
        最近更新 更多