在C#或php或其他语言中,有两种方法可以将值传递给函数,按值传递并通过引用传递它。
按值传递参数使值复制到函数中,所以这需要额外的内存空间,尽管在函数外部运行后将回收内存空间。
但是通过引用传递参数无需复制值,它可以节省内存。从这个角度来看,我们可以说使用“按引用传递”总是比“按值传递”更好吗?
答案 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)); }
当然还有更多的主题,但是因为你只是要求“ 总是更好?”我觉得一个反驳的例子就够了。 ;)
修改:问题最初被标记为c++,因此我的答案非常具体。
另一个更与语言无关的例子是当你需要复制参数时,因为你不想修改原始对象:
void function(int& val) { int v2 = val; modify(v2); use(v2); }
// vs
void function(int val) { modify(val); use(val); }
你明白了......
答案 2 :(得分:1)
按引用传递需要复制对象的引用。如果该参考在成本上与对象本身相当,则该益处是虚幻的。此外,有时你需要对象的副本,并且通过值传递给你一个。
此外,问题中的推理存在关键错误。如果按值传递,并且不需要复制该值,则不需要实际复制该值。大多数语言都有一个“as-if”规则,规定程序只需要像编译器那样按照你的要求行事。因此,如果可以避免副本,编译器可以自由地避免它。如果无法避免副本,那么您需要副本。