C ++:在这种情况下引用的优点是什么?

时间:2015-10-20 06:31:55

标签: c++ function reference

我有两段代码:

int f1(int b)
{
   return b;
}

int & f2(int b)
{
   return b;
}

这些功能有什么区别?我知道第二个返回一个引用,但由于我可以以相同的方式使用这两个函数,有什么区别?

编辑:这个功能更好吗?

int && f2(int b)
{
   return b;
}

我什么时候应该使用返回引用的函数?

Edit2:那我什么时候应该使用返回Rvalue引用的函数?

3 个答案:

答案 0 :(得分:6)

int f1(int b) {
   return b;
}

返回整数b。

int & f2(int b) {
   return b;
}

返回对函数返回时销毁的整数b的引用。换句话说,您通过值将b传递给函数,这意味着b在函数的堆栈框架中有一个地址。函数返回后,该函数的堆栈帧中的任何内容(包括您返回引用的b)都不再存在。所以,你不知道引用实际引用了什么,所以你不能使用它。

修改:您编辑的功能并不是更好。这样会更正确:

int& f2(int& b) {
   return b;
}

除非你遇到像@ user4581301这样的情况,否则你应该永远不要返回对你要返回的函数中创建的对象的引用,原因如上所述!

如果要将对象传递给函数,并让函数对该对象执行某些操作而不复制该对象,请执行以下操作:

void f2(int& b) {
    ... do stuff to b
}

答案 1 :(得分:5)

考虑一个包装数组的简单类,仅仅是为了提供一个OP可以对返回的引用做什么的例子。

class example
{
private:
    int array[]= {1,2,3,4,5,6,7,8,9,0};
public:
    int get(int index)
    {
        return array[index];
    }
    int & get2(int index)
    {
        return array[index];
    }
}

现在我们有一个例子,它不会进入未定义行为的荒地,并且可以向你展示这种全副武装的操作参考的力量。

说我们有

example x;

我们可以调用get函数来检索值

int val1 = x.get(1);
int val2 = x.get2(2)

但我们也可以

x.get2(3) = 30;

因为get2返回一个我们可以分配给它的引用,并使赋值保持不变。

如果您想要将索引运算符添加到示例

,这是非常有用的
int & operator[](int index)
{
    return array[index];
}

因为它允许预期的数组行为

int val = x[5];
x[6] = 10;

修改

Tony D带来了另一项重要功能。返回引用将返回 by 引用。除了允许修改返回的对象之外,这不会复制并节省通过制作副本所消耗的任何努力。对于整数的示例情况,这是没有实际意义的。传递整数和引用整数的成本要么相同要么接近,以至于无关紧要。对于可能需要花费大量精力进行复制的较大,更复杂的对象或不能或不应复制的对象,情况并非如此。

BigFreakingObject & getBigFreakingObject();

允许呼叫者在BigFreakingObject上操作,而不会产生重复的费用。然而,这会将密钥移交给王国,并且允许呼叫者执行BigFreakingObject BigFreakingObject权限允许的任何内容,这可能与BigFreakingObject所有者的要求相冲突。

使用

将引用声明为const
const BigFreakingObject & getBigFreakingObject();

BigFreakingObject const & getBigFreakingObject();

将提供BigFreakingObject的引用,但不允许调用者修改其状态,保护BigFreakingObject的所有者免受任何不愉快的意外。

有关详情,read up on Const Correctness

答案 2 :(得分:3)

在...

int & f2(int b)
{
   return b;
}

...参数b是调用者提供的值的自动(堆栈托管)副本:当f2返回时,回收堆栈空间。返回int&时,即使内存可供重用,您也会传回对f2的{​​{1}}变量的引用。如果您尝试使用返回的引用访问该值,则表明您有未定义的行为。