【问题标题】:C++ return by reference what are the effects?C++ 引用返回有什么影响?
【发布时间】:2017-02-27 12:00:38
【问题描述】:

看下面的代码,函数通过引用返回:

#include <cstdio>
using namespace std;

int & myFunction(int & input) {
    return input;
}

int main() {
    int x;
    int y = 10;
    x = myFunction(y);
    printf("x is %d\n",x); // x is 10
    printf("y is %d\n",y); // y is 10
    x = 20;
    printf("x is %d\n",x); // x is 20
    printf("y is %d\n",y); // y is 10
    return 0;
}

除了返回对函数局部变量的引用的明显缺陷(这里不是这种情况),在这种设置中还有什么需要注意的吗?换句话说,除了一个简单地通过引用返回内容以避免不必要的复制操作的函数之外,这段代码还有什么“更多”的东西吗?

【问题讨论】:

  • 对不起,我没有发现。这个案子没问题。
  • 不,仅此而已。事实上,它经常使用 > 操作符
  • "一个简单地通过引用返回内容以避免不必要的复制操作的函数" 是这种情况,还是您暗示将这样做作为一种优化?因为通常它是为语义而做的,而不是过早地优化。
  • 没问题,在其他地方做。就像@UKMonkey 说的流操作符一样。例如这里:en.cppreference.com/w/cpp/string/basic_string/operator_ltltgtgt
  • 此代码类似于 std::ostream 的标准运算符

标签: c++ reference pass-by-reference return-by-reference


【解决方案1】:

您提供的代码有效,因为您通过引用将变量传递给您的函数,并且仍然通过引用返回它。这是一致的并且有效,但很奇怪。为什么要返回通过引用传递的相同变量? (我刚刚从 cmets 中记得,这对于在 std::ostream 中进行链接很有用。)

另一方面,如果您按值传递该变量,您将有一个悬空引用并且它不起作用。所以这行不通

int & myFunction(int input) {
    return input;
}

在我看来,我认为唯一合适的引用返回是从类的方法中返回一个变量。除此之外,我认为您根本不应该通过引用返回。

你可以catch一个变量作为一个常量引用,如果你想避免复制它而没有悬空,如果你这样做:

int myFunction(int input) {
    return input;
}

int main()
{
    const int& myInt = myFunction();
    //myInt is still valid here
}

这是一种特殊情况。

【讨论】:

  • 我的意思是第一部分是在 stl 本身中完成的。以及关于价值传递。问题中指出OP知道这一点。
  • 谢谢,我问的是这个特定的情况(即我们没有错误地返回对局部变量的引用)。这种情况还有什么“更多”吗?
  • @space_voyager 我不明白你为什么会那样做。通过引用传递并通过引用返回相同的变量是非常模棱两可和不可读的......
  • @TheQuantumPhysicist 它完全可读;事实上,它有助于提高可读性!让我们看看 cout
  • @UKMonkey 好吧,你是对的。这对于链接也很有用。我忘记了。
【解决方案2】:

除了返回对本地的引用的明显缺陷 函数的变量(这里不是这种情况),有没有 在这种设置中需要注意什么?

不,不是真的,它完全有效,但也没有任何优势。 (当前状态为myFunction

为了避免不必要的复制操作?

这里还有一个副本:

int x;
int y = 10;
x = myFunction(y); // value of y is copied to x.

这不太可读,并且在正常初始化时不会加速任何事情:

int x;
int y = 10;
x = y;

在这种情况下没有理由这样做,只需坚持正常初始化即可。

当然,如果myFunction 对比int&amp; 更复杂的对象添加某种修改,那么您可以利用返回引用的优势:

chain.method().calls();

【讨论】:

  • 谢谢!是的,当然 myFunction() 没有用,因为它在我的示例代码中。我只是举一个我们可以讨论的最小例子。
猜你喜欢
  • 1970-01-01
  • 2018-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-15
  • 1970-01-01
相关资源
最近更新 更多