c++ - 在 C++ 中从函数返回中引用运算符 & 的使用

标签 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;
}

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

double& setValues(int i);

我得到的错误是“左值需要作为赋值的左操作数” 这是否意味着值 vals[i] 应该放在右边?使用 & 运算符,这部分变为左值?

最佳答案

当您创建变量或数组并为它们命名时,它们会预留一 block 内存区域供它们定位。

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 的永久(大概)位置在 temporary 被销毁之前。

因此,允许创建临时对象的表达式存在于赋值的右侧是很有用的,它们的值可以被捕获在作业的左侧

但反之则不然:

setValue(3) = 70.8; // not allowed

原因是 setValue(3) 返回数组中值的临时拷贝,该拷贝将在赋值后立即销毁。因此,如果这样一个临时值将在之后立即被删除,那么允许写入这样一个临时值是没有意义的。

此外,如果编译器允许对这样的临时对象进行赋值,它就必须为它预留实际内存(而不仅仅是 CPU 寄存器),并且编译器会在很多地方失去处理的机会更有效地处理临时文件。

当您通过使用所有更改的reference 声明符将函数更改为返回reference 时:

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

返回的是访问数组本身的实际值。这不是临时值,而是驻留在主内存中的永久值。

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

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

关于c++ - 在 C++ 中从函数返回中引用运算符 & 的使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36009354/

相关文章:

c++ - 传递对 C++ 中的映射的引用

c++ - 持有大量共享状态的访问者类 : best way to implement reference semantics?

c - 将所有变量声明为指针与在 C 中使用地址运算符

c++ - 避免无意中复制对象——可用的技术

c# - 如何将字节转换为字符串?

c++ - 堆或栈数组。用户定义的类型难题

c++ - CLion 中的 allegro5 项目,ld : library not found error

c++ - printf() 似乎改变了一个变量

javascript - 当我明确表示我不希望它通过引用传递数组时

c++ - Makefile 目标错误