【问题标题】:Difference between returning reference vs returning value C++返回引用与返回值 C++ 之间的区别
【发布时间】:2013-04-06 06:36:08
【问题描述】:

关于为什么有必要从函数返回引用的问题。

如果我们将第 9 行和第 16 行中的int& 替换为int,则以下代码的行为完全相同。

在我的示例代码中是否如此,返回引用与值无关紧要?在什么样的例子中它会开始变得重要?

在我看来,我们不能返回函数的局部变量的引用,因为局部变量将超出调用者的范围。因此,仅返回调用者可以看到(在范围内)的变量的引用才有意义,但是如果函数的调用者可以看到该变量,则不需要返回(?)(或者这是返回为了保持代码整洁而做的?)

相关链接:Is returning a reference ever a good idea?

#include <iostream>
using namespace std;

class myClass{
private:
    int val;
public:
    myClass(int);
    int& GetVal();
};

myClass::myClass(int x){
    val = x;
}

int& myClass::GetVal(){
    return val;
}

int main()
{
    myClass myObj(666);
    cout << myObj.GetVal() << endl;
    system("pause");
    return 0;
}

【问题讨论】:

  • 如果将结果分配给参考变量然后修改该变量,可以看出差异。如果您只在表达式中使用结果,则没有区别。

标签: c++ reference


【解决方案1】:

不同的是,当你返回一个引用时,你可以赋值给GetVal()的结果:

myObj.GetVal() = 42;

您也可以保留返回的引用,并在以后使用它来修改myObj.val

如果GetVal() 按值返回val,这一切都不可能。

这是否是可取的,或者确实是好的设计,完全是一个不同的问题。

请注意,您的示例与 linked question 中的代码非常不同——该代码返回无效引用,这无疑是个坏主意。

【讨论】:

  • 谢谢,在这里学到了一些新东西。但是,我的下一个问题是“这是否是可取的”但是我问一个更简单的问题:是否存在如果不返回引用就无法完成任务的情况?就像其他答案所表明的那样,修改类的私有成员的能力似乎是一种不受欢迎的情况。 (我无法想象我们希望通过引用返回的任何理想情况)
  • @SidaZhou:在很多情况下这是可取的。例如,如果vstd::vector,则v[i] 返回一个引用。这让你可以写v[i] = 42,这比s.set(i, 42)更容易看。
【解决方案2】:

在这种情况下,不同之处在于通过引用返回允许调用者通过为其分配值来修改数据成员,而通过值返回仅返回调用者变量的副本。

首先允许你写:

myObj.GetVal() = 100;

而后者没有。

请注意,第一种方式允许函数的调用者获取对private 数据成员的引用,并且他们可以随意修改它。对我来说,这是我想避免的事情。我不希望我班级的用户随意更改班级成员的状态。

【讨论】:

    【解决方案3】:

    除非您返回这样的参考代码是非法的

    int main()
    {
        myClass myObj(666);
        myObj.GetVal() = 777;
        return 0;
    }
    

    所以一个重要的问题是你是否希望这样的代码是合法的。在这种情况下我会说不是,但其他情况可能会有所不同。

    对于您的另一点,您几乎是对的,但这与用户是否可以看到变量无关,而与变量的生命周期有关。用户可能看不到变量(例如它可能是私有的),但只要变量仍然存在,那么返回对它的引用就不会出错。

    对于复杂的对象,还有一个问题是您是要复制对象还是返回对原始的引用。但是,对于像 int 这样的简单类型,这不太可能成为问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-12-18
      • 2011-05-24
      • 1970-01-01
      • 2016-01-03
      • 2016-05-27
      • 2017-07-18
      • 2017-07-14
      相关资源
      最近更新 更多