在C ++函数参数中使用&运算符:pass-by-rvalue-reference

Use of & operator in C++ function parameters: pass-by-rvalue-reference

本问题已经有最佳答案,请猛点这里访问。

我对这个代码片段有点惊讶!调用方正在传递值,但函数如何处理其地址?

1
2
3
4
5
6
7
8
void increase1(int &value) {
   value++;
}

int main() {
   int number = 5;
   increase1(number);
}

如果有人详细解释的话会很有帮助。谢谢您。


'increase1(int&value)'采用'l-value引用'。在C++ 11之前,我们只学习了"引用"。所有参考均为L值。

L值是什么?L值的简化定义是编译器可以提供地址的东西。因此,变量(如value)具有物理存储位置(假设其内存位置没有优化)。

一个标量,如5,甚至是两个变量的和,如x + y都没有内存位置。编译器不在内存中存储5。相反,它将一个5移动到number的存储位置。编译器不将x + y存储为内存位置。同样,在简化的基础上,5是一个概念,(x+y)是一个概念——这些是r值。对r值的引用是第二种引用类型[此处不讨论]。

回到您的好例子,int &value描述了一个l值引用,因为value表示内存中的一个位置。

main()函数(假设没有优化)

  • 声明number为int,并为number分配、存储。在大多数32位和64位系统上,为数字分配了4个字节的内存。
  • 5是R值。编译器创建一条移动指令,将5移动到内存中的数字位置。
  • main()现在通过传递数字的存储位置来调用increase1()。变量是通过引用传递的,这意味着地址被传递给increase1main()知道传递地址,因为'increase1()接受L值引用。
  • increase1()接收到数字的地址,将其解引用得到5个值,在解引用的指针上加一个,然后将结果存储回地址为number的位置。
  • L值引用允许被调用函数直接修改调用方拥有的存储。

    请注意,存储地址是传递的。地址可以来自main()的堆栈,也可以来自堆(由new分配)。在本例中,main()从堆栈中分配number,但不必从堆栈中分配。

    一种非常冗长的说法,即L值引用将使用地址传递,除非编译器认识到它可以通过优化更快地传递。如果编译器优化了引用的实际通道,那么逻辑理解仍然有效。


    这是一个参考。

    1
    2
    3
    `int a;   //variable
    int @a;  //reference
    int *a;  //pointer`

    引用就像一个指针,您必须先初始化,不能更改。但您可以更改该地址的值。在申报之后,你不需要在它之前加*号。

    右声明示例:int &a=b;现在要使用它,只需写A,当你改变A时,同样的改变也会发生在B上。


    由于increase1引用int,调用者自动通过引用发送值。

    通过引用发送值的功能与发送指针的功能相同,但

    • 你不必记地址,它会自动记下来的
    • 可以像使用正则变量一样使用引用
    • 假定引用不为空。这很有用,因为这意味着您不必在接受引用的函数内执行空检查。

    如果引用来自指针,请在将指针转换为引用之前检查以确保指针不为空。如果您已经知道指针不是空的,那么您就不必检查(当然)。