我应该在哪里选择传递引用或按值传递?

时间:2011-02-13 19:29:45

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

在什么情况下我更喜欢传递参考?通过按值?

7 个答案:

答案 0 :(得分:30)

有五种主要情况,你应该使用pass-by-reference而不是pass-by-value:

  1. 如果你正在调用一个需要修改其参数的函数,请使用pass-by-reference作为获得此效果的唯一方法(在这种情况下,我可以交替使用pass-by-reference和pass-by-pointer,虽然使用pass-by-pointer通常需要显式检查NULL)。
  2. 如果您正在调用需要将大对象作为参数的函数,请通过const引用传递它,以避免对该对象进行不必要的复制并大幅提高效率。
  3. 如果您正在编写一个复制构造函数,根据定义必须使用引用,请使用按引用传递。
  4. 如果您正在编写一个想要对多态类进行操作的函数,请使用按引用传递或通过指针传递以避免切片。
  5. 如果您正在编写可能返回非常大或不可复制对象的函数,请使用按引用传递作为使用参数存储生成的值的方法。

答案 1 :(得分:7)

有几个注意事项,包括:

<强>性能

按值传递会复制数据,因此按值传递大型数据结构会抑制性能。通过引用传递仅将引用(基本上是地址)传递给数据。对于大型数据结构,这可以大大提高性能。对于较小的数据结构(如int),通过引用传递可能会抑制性能。

<强>修饰

按值传递会复制数据,因此如果目标代码修改了该副本,则不会影响原始数据。通过引用传递仅传递数据的地址,因此对该引用所做的修改将对调用代码“可见”。

答案 2 :(得分:2)

传递值,例如本机类型,它们足够小以直接传递它们是有效的。否则使用传递(const)引用。

困难的部分是编写一个可以应用于任何一个的模板(在这种情况下,你通常希望使用按引用传递 - 通过值传递大对象的潜在惩罚比通过的潜在惩罚要差得多当通过值时的参考将是首选的。)

编辑:当然,这是假设一种情况,其中所需的语义将允许任何一个 - 显然如果你正在使用像多态对象这样的东西,没有涉及真正的“偏好”,因为你必须使用指针或引用来获得正确的行为。

答案 3 :(得分:2)

由于其他人已经足够好地回答了你的问题,我想补充一点:

如果班级拥有public复制构造函数,那么您无法选择按值传递;你必须通过引用传递(或者你可以传递指针)。

以下程序无法编译:

class A
{
public:
     A(){}
private:
     A(const A&) {}
};

//source of error : pass by value
void f(A ) {}

int main() {
        A a;
        f(a);
    return 0;
}

错误:

  

prog.cpp:在函数'int main()'中:
  prog.cpp:10:错误:'A :: A(const A&amp;)'是私人的   prog.cpp:18:错误:在此上下文中   prog.cpp:18:错误:初始化'void f(A)'

的参数1

在ideone上看自己:http://www.ideone.com/b2WLi

但是一旦你通过引用传递函数f,那么它编译得很好:http://www.ideone.com/i6XXB

答案 4 :(得分:1)

您已使用C和C ++标记了您的问题。

因此,我建议您考虑在支持此功能的C ++中使用pass by reference,并且不考虑在不支持此功能的C中使用它。

答案 5 :(得分:0)

通过引用传递只能在以下情况下调用:

按引用传递比按值传递更有效,因为它不复制参数。形式参数是该参数的别名。当被调用函数读取或写入形式参数时,实际上就是对参数本身的读取或写入。

按引用传递和按值传递之间的区别在于,对被调用函数中的按引用传递的参数进行的修改在调用函数中有效,而对按值传递的参数在被调用函数中进行的修改函数不会影响调用函数。

如果要在调用函数中修改参数值,请使用传递引用。否则,请使用按值传递来传递参数。

引用传递和指针传递之间的区别是

指针可以为NULL或重新分配,而引用则不能。 如果NULL是有效的参数值,或者要重新分配指针,请使用传递指针。 否则,请使用常量或非常量引用来传递参数。

答案 6 :(得分:-3)

虽然指针是引用,但c ++中的“reference”通常是指标记SomeType&amp;参数的做法。

你永远不应该这样做。唯一合适的地方是实现各种预定义运算符所需的神奇语法。否则:

  • 你永远不应该通过引用传递参数 - 通过指针传递,否则你只能进行代码审查。通过引用传递使得无法通过检查调用可以预期哪些参数被更改来判断。

  • 您也不应该通过引用传递参数。同样,这意味着您正在执行元优化。你应该总是只是按值传递,否则你在一个对象内部偷看,检查它的实现并决定由于某种原因首选pass-by-reference是有罪的。

任何c ++类都应该实现所有需要按值传递的复制和赋值构造函数和重载。否则它没有完成它的工作,从程序员的实现细节中抽象出程序员。