我们可以说使用“按引用传递”总是比“按值传递”更好吗?

时间:2013-08-25 03:30:32

标签: pass-by-reference

在C#或php或其他语言中,有两种方法可以将值传递给函数,按值传递并通过引用传递它。

按值传递参数使值复制到函数中,所以这需要额外的内存空间,尽管在函数外部运行后将回收内存空间。

但是通过引用传递参数无需复制值,它可以节省内存。从这个角度来看,我们可以说使用“按引用传递”总是比“按值传递”更好吗?

3 个答案:

答案 0 :(得分:2)

通过引用传递和传递值在语义上是不同的,有时一个是正确的方法,有时是另一个。在许多情况下,手头的任务已经规定了需要哪种方法,并且在只支持一种选项的情况下,您经常需要手动解决它(例如,如果您需要Java副本,则需要clone()对象)。

在泛型函数的上下文中,答案与您提出的首选项的方式相反:通过值传递推导类型的参数!原因是你可以使用std::ref()之类的东西来获取引用语义,但是如果函数使用引用语义,则无法获得值语义。

答案 1 :(得分:2)

有很多情况下你想要传递价值。

示例可能是您需要const Type&Type&&重载时。按值传递只处理两种情况而不必复制任何代码:

void function(Object o) { do_something_with(std::move(o)); }

相反:

void function(Object&& o) { do_something_with(std::move(o)); }
void function(const Object& o) { do_something_with(Object(o)); }

当然还有更多的主题,但是因为你只是要求“ 总是更好?”我觉得一个反驳的例子就够了。 ;)

修改:问题最初被标记为,因此我的答案非常具体。


另一个更与语言无关的例子是当你需要复制参数时,因为你不想修改原始对象:

void function(int& val) { int v2 = val; modify(v2); use(v2); }
// vs
void function(int val) { modify(val); use(val); }

你明白了......

答案 2 :(得分:1)

按引用传递需要复制对象的引用。如果该参考在成本上与对象本身相当,则该益处是虚幻的。此外,有时你需要对象的副本,并且通过值传递给你一个。

此外,问题中的推理存在关键错误。如果按值传递,并且不需要复制该值,则不需要实际复制该值。大多数语言都有一个“as-if”规则,规定程序只需要像编译器那样按照你的要求行事。因此,如果可以避免副本,编译器可以自由地避免它。如果无法避免副本,那么您需要副本。