按值传递或按引用传递

Posted

技术标签:

【中文标题】按值传递或按引用传递【英文标题】:Passing by value or passing by reference 【发布时间】:2012-01-16 01:21:50 【问题描述】:
void Subroutine1(int Parameter1)

void Subroutine2(const int &Parameter1) 

在 Subroutine1 中,我们必须获取参数的副本,而在 Subroutine2 中,我们不必制作副本,这可能会节省一些开销。

实际上,Subroutine1 似乎比另一个更频繁地使用。为什么会这样?

【问题讨论】:

如果使用 int,则不会节省任何开销,因为传递指向 int 的指针所花费的时间/内存与传递 int 的副本一样多。 【参考方案1】:

实际上,Subroutine1 似乎比另一个更常用。 为什么会这样?

因为复制一个 int 比创建一个引用(或指针)然后访问它更好。

更一般地说,所有原始类型都应该按值传递。

【讨论】:

【参考方案2】:

因为当您处理原始类型(例如int)时,按引用传递实际上比按值传递在性能方面更糟糕。它也没有为您提供任何东西。

【讨论】:

为什么“传递指针而不是引用更为传统”? @TerryLiYifeng:因为数十年的 C 代码都是这样做的,所以你更有可能看到人们遵循这个例子。但是在这种情况下使用引用在技术上没有任何问题。 @downvoter:请留下评论帮助我改进这个答案。 @Jon 只有不习惯 C++ 的旧 API 和 C 程序员仍然以这种方式执行多个返回值。此外,多返回值的事情不适用于有关按值传递与按 const& 传递的问题。 @Dave:很公平。删除了第二段,只保留答案中的相关位。【参考方案3】:

一个传递一个int,另一个传递一个引用。正如其他人所说,创建和访问对 int 的引用与复制 int 没有太大区别。

(根据正确评论编辑)

【讨论】:

这不是大小的问题。如果通过指针实现引用,则增加了取消引用该指针的开销。【参考方案4】:

通过引用传递(几乎总是)通过传递指针来实现。这意味着,对于像int 这样的简单类型,第二个版本的效率可能较低——传递指针的成本与传递简单对象的成本差不多,然后函数需要取消引用该指针。

【讨论】:

【参考方案5】:

对于通常较小的原始数据类型(如intdoublechar),与第二种情况相比,第一种情况通常更快(可访问性)且更便宜。请记住,引用的实现或多或少类似于指针。

附带说明,如果Parameter1不打算修改,那么我个人会选择第三种替代方案,

void Subroutine3(const int Parameter1);

【讨论】:

在这里添加 const 有什么意义,因为 Parameter1 的原始数据无论如何都不会改变? 确实,void Subroutine3(const int Parameter1);void Subroutine3(int Parameter1); 声明了相同的函数,因此没有理由在声明中(在标题中)列出您的实现细节。 @TerryLiYifeng,目的是提一下Parameter1在函数内部没有改变。【参考方案6】:

在某种程度上,引用传递意味着被调用者可以改变所引用的任何内容,并使该改变在调用者中生效。如果是这种情况,您可能希望将 int 包装为一个对象并通过引用将其传递给函数。这提供了更明确的代码。

【讨论】:

【参考方案7】:

首先,对于int类型,传值比传引用快。但是对于你自己的类和结构,通过 ref 更快。

这两种方法对于原始类型的开销差异实际上非常小,在大多数情况下您可以忽略它。

在我看来,原始类型参数的 const ref 对普通函数没有用处。而且它使代码有点晦涩,所以不要使用它。

【讨论】:

以上是关于按值传递或按引用传递的主要内容,如果未能解决你的问题,请参考以下文章

按值传递或按引用传递

java:按值传递或按引用传递[重复]

R按值传递或按引用传递[重复]

第7章 按值传递或按引用传递:7.5 处理返回值

第7章 按值传递或按引用传递:7.6 推荐的模板参数声明方法

第7章 按值传递或按引用传递:7.3 使用std::ref()和std::cref()