我想了解这里发生了什么。显然,参考或赋值运算符的某些方面我没有做对。
目标:在一个函数中,我希望将2个本地引用变量用于同一个列表的各个元素:一个是迭代的,一个是"标记"在满足某些条件时会发生变化。两者最初都引用相同的元素。我没有修改列表中的字符串(在实际代码中,列表是通过引用传递的参数)。
问题:只要将第二个引用更改为另一个元素,第一个引用现在也指向该新元素。引用保持同步,但我希望它们是独立的。
我的解释:迭代器是指向列表中包含的字符串的指针。在string & ref1 = *it
中,我解除引用迭代器指针以获取字符串地址(无论它本身是指针也不应该对IMO非常重要),以便ref1
和ref2
为&#34 ;别名"到字符串" a"的地址。所以在我看来,更改ref2使其指向另一个字符串不会改变任何地址,但只是ref2的值现在应该指向或者#34;别名"字符串" b",而ref1仍应指向" a"。
更改代码使用指针而不是引用是完美的,所以我似乎错误地将引用变量视为指针,或者幕后有什么东西(重载的赋值运算符?)我没想到的。
list<string> l;
string s1 = "a";
string s2 = "b";
l.push_back(s1);
l.push_back(s2);
list<string>::iterator it = l.begin();
string & ref1 = *it;
string & ref2 = *it;
++it; // After this line, both ref1 && ref2 evaluates to "a"
ref2 = *it; // After this line, both ref1 && ref2 evaluates to "b"
if(ref1 == ref2){
cout << "woot!" << endl;
}
答案 0 :(得分:4)
string & ref1 = *it;
string & ref2 = *it;
好的,所以你创建了两个对同一个字符串的引用。
++it; // After this line, both ref1 && ref2 evaluates to "a"
是的,因为它们都是对同一个字符串的引用。这就是你创建它们的方式。
ref2 = *it; // After this line, both ref1 && ref2 evaluates to "b"
是的,因为它们都是对同一个字符串的引用,而你只是用一个来改变它所引用的字符串的值。
所以在我看来,更改ref2使其指向另一个字符串不会改变任何地址,但只是ref2的值现在应该指向或“别名”为字符串“b”,而ref1仍应指向“一个”。
这不是参考工作的方式。这就是参考工作的方式:
int a, b;
int& ref = a;
ref = b; // same as a=b, does not "re-seat" the reference
如果您想要一个可以“重新就位”的引用,请使用std::reference_wrapper。
答案 1 :(得分:1)
引用类似于指针,您无法更改指向的地址。分配给引用与分配给它指向的地址相同,而不是分配给指针:
int x = 5;
int& xref = x;
// equivalent to:
int* const xptr = &x;
xref = 10;
// equivalent to:
*xptr = 10;