使用参考运算符&从c ++中的函数返回

时间:2016-03-15 11:00:30

标签: c++ pass-by-reference

我在代码中感到困惑:

#include <iostream>
#include <ctime>
using namespace std;
double vals[] = { 10.1, 12.6, 33.1, 24.1, 50.0 };

double& setValues(int i)//if i remove the &operator, i get an error, why ?
{
    return vals[i]; // return a reference to the ith element
}

int main()
{
    cout << "Value before change" << endl;
    for (int i = 0; i < 5; i++)
    {
        cout << "vals[" << i << "] = ";
        cout << vals[i] << endl;
    }
    setValues(1) = 20.23; // change 2nd element
    setValues(3) = 70.8; // change 4th element
    cout << "Value after change" << endl;
    for (int i = 0; i < 5; i++)
    {
        cout << "vals[" << i << "] = ";
        cout << vals[i] << endl;
    }
    return 0;
}

如果我删除&amp;函数中的运算符

double& setValues(int i);

我得到的错误是'作为赋值的左操作数所需的l值' 这是否意味着值vals [i]应该放在右边?和&amp;运算符这部分变为l值?

2 个答案:

答案 0 :(得分:2)

  

这是否意味着值vals [i]应该放在右边?

没有。 vals[i]可以是赋值运算符的左操作数和右操作数。从函数返回的double value 不能是操作符的操作数。

  

与&amp;运算符这部分变为l值?

&不是运算符,而是声明符的一部分。使用&,从函数返回引用,您可以将其用作运算符的左操作数。

答案 1 :(得分:2)

当你创建一个变量或一个数组,给它们命名时,它们会留出一个存储区域,供它们找到。

double vals[] = { 10.1, 12.6, 33.1, 24.1, 50.0 };

该数组的每个元素都有一个不同的内存地址。

没有&引用声明符的函数将只返回数组中值的副本

double setValues(int i); // return a copy of a value from the array

这个副本的问题在于它没有永久存在于内存中。它就是我们所说的临时值,只有创建它的表达式才会存在。表达式结束后,临时值将被销毁。

所以:

double d = setValue(3); // okay

尽管函数名称不太合适,但编译器允许这样做,因为数组中值的临时副本存储在名为d的永久(ish)位置之前< em>临时被销毁。

因此,允许创建 temporaries 的表达式存在于分配的右侧中是有用的,其中值可以捕获通过作业的左侧

但事实恰恰相反:

setValue(3) = 70.8; // not allowed

原因是setValue(3)返回数组中值的临时副本,它将在赋值后立即销毁。因此,如果将其值立即删除,则允许写入临时值是没有意义的。

另外,如果编译器允许对这样的临时赋值,则必须为它预留实际内存(而不仅仅是CPU寄存器),当编译器失去交易机会时会有很多地方暂时更有效率。

使用引用声明符更改函数以返回引用时所有更改:

double& setValues(int i); // return access to the value in the array

返回的是访问数组本身的实际值。这是临时值,但永久(ish)值驻留在主存储器中。

所以现在编译器允许你改变它的值是有意义的,因为它在表达式结束后不会被销毁,但是它会继续存在,直到数组本身被销毁。

setValue(3) = 70.8; // now it is good - changes the array itself