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

use*_*748 2 c++ reference function

我有两段代码:

int f1(int b)
{
   return b;
}

int & f2(int b)
{
   return b;
}
Run Code Online (Sandbox Code Playgroud)

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

编辑:这个功能更好吗?

int && f2(int b)
{
   return b;
}
Run Code Online (Sandbox Code Playgroud)

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

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

Ale*_*sky 6

int f1(int b) {
   return b;
}
Run Code Online (Sandbox Code Playgroud)

返回整数b.

int & f2(int b) {
   return b;
}
Run Code Online (Sandbox Code Playgroud)

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

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

int& f2(int& b) {
   return b;
}
Run Code Online (Sandbox Code Playgroud)

除非您遇到类似@ user4581301给出的示例,否则您应该永远不会返回对您要返回的函数内创建的对象的引用,原因如上所述!

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

void f2(int& b) {
    ... do stuff to b
}
Run Code Online (Sandbox Code Playgroud)


use*_*301 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];
    }
}
Run Code Online (Sandbox Code Playgroud)

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

说我们有

example x;
Run Code Online (Sandbox Code Playgroud)

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

int val1 = x.get(1);
int val2 = x.get2(2)
Run Code Online (Sandbox Code Playgroud)

但我们也可以

x.get2(3) = 30;
Run Code Online (Sandbox Code Playgroud)

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

如果要在示例中添加索引运算符,这是非常有用的

int & operator[](int index)
{
    return array[index];
}
Run Code Online (Sandbox Code Playgroud)

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

int val = x[5];
x[6] = 10;
Run Code Online (Sandbox Code Playgroud)

编辑

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

BigFreakingObject & getBigFreakingObject();
Run Code Online (Sandbox Code Playgroud)

将允许呼叫者在a上运行BigFreakingObject而不会产生重复它的成本.然而,这将把钥匙交给王国,并允许来电者做BigFreakingObject任何BigFreakingObject允许的权限,这可能与BigFreakingObject所有者的要求相冲突.

声明引用作为const

const BigFreakingObject & getBigFreakingObject();
Run Code Online (Sandbox Code Playgroud)

要么

BigFreakingObject const & getBigFreakingObject();
Run Code Online (Sandbox Code Playgroud)

将提供BigFreakingObject但不允许呼叫者修改其状态的参考,保护所有者BigFreakingObject免受任何不愉快的意外.

有关详细信息,请阅读Const Correctness.

  • @ user2738748值得注意的是,函数也可以返回`const`引用,它不允许修改引用的对象,但是可以在不复制的情况下访问该值:当对象很大时可以更有效,并且主动不可复制的对象所需的(例如删除的复制构造函数).即使对于`const`引用,它们也只能在引用对象的生命周期中使用(即对`f2`函数参数的访问仍然会被破坏). (2认同)