引用和const引用之间的区别作为函数参数?

时间:2009-11-12 04:08:25

标签: c++ reference

这是一段简单的C ++代码片段:

A foo(){
  A a; // create a local A object
  return a;
}

void bar(const A & a_r){

}

bar(foo());

为什么函数栏的参数必须是const引用,而不仅仅是引用?

Edit1:我知道参考是为了避免复制开销。和const是只读的。但是在这里我必须使它成为const引用,否则如果我删除“const”,g ++将向我抛出错误。

Edit2:我的猜测是foo()的返回对象是一个临时对象,不允许更改临时对象的值?

5 个答案:

答案 0 :(得分:5)

没有错误消息,我不确定编译器可能会抱怨什么,但我可以逻辑地解释原因:

在行中:

bar(foo()); 

foo()的返回值是临时A;它是通过调用foo()创建的,然后在bar()返回后立即销毁。执行非常量操作(即更改临时A的操作)没有意义,因为对象A在之后被破坏。

再看一点,这是这个问题的虚拟副本:

How come a non-const reference cannot bind to a temporary object?

有一个很好的答案。

答案 1 :(得分:0)

引用必须引用const对象,因为无论如何您都无法使用它。比较以下代码段:

void bar(A&);   
A x = foo();
bar(x);
if (x.member) {...} else {...}

void bar(A const&);   
bar(foo());
if (//x? we don't have any x! We can't branch here!

虽然在第一个例子中,修改对象的能力可能会显着改变后续代码的执行,但在第二个例子中我们没有办法(我们可以参考的变量名)来执行它。因此,我们只能使用对const的引用,想要对象不被修改。

答案 2 :(得分:0)

  

为什么功能栏的参数   必须是一个const引用,而不仅仅是   参考?

bar()的参数不必是const引用。但是当将对象传递给函数参数时,当函数不修改对象时,它是最有效的方法。

  • 使参数保持不变可确保编译器在您尝试修改对象时发出警告。
  • 传递参​​数作为参考不会创建对象的副本,因此可以实现效率。

答案 3 :(得分:0)

编译器正在寻找bar(const foo&),因为您将const reference to foo传递到bar中的bar(foo()) - 这是因为您正在传递对临时变量的引用bar返回后不存在

没有用例通过引用修改foo内的bar是有意义的,因为从bar()返回后它将不存在。

因此编译器强制执行此操作以防止开发人员将引用引用到临时的隐藏错误并更新临时对象,该对象将在方法返回后消失。

答案 4 :(得分:0)

代码bar(foo())将一个左值传递给bar()。只有右值可以具有指向它的指针或引用。 lvalue可以具有const引用,因为const限制阻止了对不存在的lvalue的赋值操作。