我试图在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。拥有整数向量的事实是否会产生影响?
答案 0 :(得分: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
引用它)。这会将x
的内容替换为y
的内容,即2
。
r.push_back(5);
s.push_back(6);
x
(r
和s
都引用)现在包含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 5
,y
将包含2 6
。
请注意,创建指向对象的指针(获取对象的地址)的语法需要显式使用address-of运算符&
。同样,取消引用指针需要显式语法:*p
用于简单地获取指向的对象,或p->m
用于访问m
指向的对象的成员p
。 / p>
答案 1 :(得分:4)
引用绑定到对象一次,永远不能重新设置。根本就没有语法。正如您在使用例如s.push_back
,只要您命名s
,即表示您正在访问指示对象 r
(实际上,x
实际上是s=y
。
因此,x=y
不会使引用引用另一个向量。你在这里做的和x
一样。最初在Dictionary<string, ArbirartyModel[]>
中的所有元素都将丢失。
Java中的引用语义与C ++中的引用语义几乎没有关系。你最好立即停止尝试比较两者,或者从一个到另一个“过渡”。以干净,清新的心态来到C ++。
答案 2 :(得分:2)
s=y;
s
所指的x
分配y
会导致将x
复制到x
覆盖(1,3,4)。所以y
变为(2)然后附加5和6.同时In case of static block:
保持不变,最后是(2)。