为什么对同一个对象的两个局部引用保持同步?



我想知道这里发生了什么。显然,引用或赋值操作符的某些方面我没有搞对。

目标:在一个函数中,我想使用2个本地引用变量来处理同一列表的各个元素:一个是迭代过的,一个是"标记",当满足某些条件时改变。两者最初都引用相同的元素。我没有修改列表中的字符串(在实际代码中,列表是通过引用传递的参数)。

问题:一旦将第二个引用更改为另一个元素,第一个引用现在也指向该新元素。引用保持同步,但我希望它们是独立的。

我的解释: iterator是指向列表中包含的字符串的指针。在string & ref1 = *it中,我对迭代器指针解引用以获得字符串地址(它本身是否是指针并不重要),因此ref1ref2是字符串"a"地址的"别名"。所以在我看来,改变ref2,所以它指向另一个字符串不会改变任何东西的地址,但只是ref2的值现在应该指向或"别名"字符串"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;    
}
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应该仍然指向"a"。

引用不是这样工作的。引用是这样工作的:

int a, b;
int& ref = a;
ref = b; // same as a=b, does not "re-seat" the reference

如果你想要一个可以"重新定位"的引用,使用std::reference_wrapper

引用类似于指针,你不能改变它指向的地址。给引用赋值与给它所指向的地址赋值相同,而不是给指针赋值:

int x = 5;
int& xref = x;
// equivalent to:
int* const xptr = &x;
xref = 10;
// equivalent to:
*xptr = 10;

相关内容

最新更新