我的参考变量发生了什么

What is happening with my reference variables?

本文关键字:什么 发生了 变量 参考 我的      更新时间:2023-10-16

我试图掌握C++引用的窍门(我想我已经在Java和Javascript中掌握了它,但过渡比我想象的要困难(。这是一狙击代码,其结果我不明白:

#include <iostream>
#include <vector>
int main()
{
    std::vector<int> x;
    x.push_back(1);
    std::vector<int> y;
    y.push_back(2);
    
    std::vector<int>& r=x;
    r.push_back(3);
    
    std::vector<int>& s=r;
    s.push_back(4);
    
    s=y;
    r.push_back(5);
    s.push_back(6);
    
    std::cout<<"x: ";
    for(int i: x) {std::cout<< i<< " ";} std::cout<<"n";
    
    std::cout<<"y: ";
    for(int i: y) {std::cout<< i<< " ";} std::cout<<"n";
    
}

我得到以下输出(使用 g++ 4.9.2(:

x: 2 5 6

y: 2

我不明白这一点:元素 1、3、4 变成了什么?我本来期望 x 是 1,3,4,5,y 是 2,6。拥有整数向量的事实会有所不同吗?

重要的一点:引用是不可恢复的。初始化引用后,它将始终引用同一对象。

现在让我们一步一步地分析你的代码:

std::vector<int> x;
x.push_back(1);

x 是一个包含 1 的向量。

std::vector<int> y;
y.push_back(2);

y 是一个包含 2 的向量。

std::vector<int>& r=x;
r.push_back(3);

r是对x的引用,现在包含1 3

std::vector<int>& s=r;
s.push_back(4);

s是对x的引用,现在包含1 3 4

s=y;

现在,您已将向量y复制到向量x(通过引用它的引用s(。这会用y的内容替换x的内容,即2

r.push_back(5);
s.push_back(6);

x(rs都引用(现在包含2 5 6

y在创建后的单push_back之后从未被修改过,因此它只包含2 .


Java称之为"引用"的概念实际上是"指针"在C++中的含义。使用指针,代码将如下所示:

std::vector<int>* r = &x;
r->push_back(3);
std::vector<int>* s = r;
s->push_back(4);
s = &y;
r->push_back(5);
s->push_back(6);

然后,x将包含1 3 4 5y将包含2 6

请注意,创建指向对象的指针(获取对象的地址(的语法需要显式使用 address-of 运算符 & 。同样,取消引用指针需要显式语法:*p用于简单地获取指向的对象,p->m用于访问p指向的对象的成员m

引用绑定到对象一次,并且永远不能重新拔插。根本没有语法。正如您在使用例如 s.push_back,每当您命名s时,您都会访问所指r(通过扩展,实际上是x(。

因此,s=y不会使引用引用另一个向量。你在这里做的事情和x=y一样。最初在x中的所有元素都丢失了。

Java 中的引用语义

与 C++ 中的引用语义的关系几乎为零。你最好立即停止试图比较两者,或者从一个"过渡"到另一个。带着干净、清新的头脑来到C++。

赋值s=y;其中s引用x,导致将y复制到覆盖 (1,3,4( 的x。所以x变成 (2(,然后附加 5 和 6。与此同时,y保持不变,最终(2(。