我们可以在 C++ 中重新分配引用吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9293674/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can we reassign the reference in C++?
提问by Invictus
I have read everywhere that a reference has to be initialized then and there and can't be re-initialized again.
我在任何地方都读到过引用必须在当时和那里初始化并且不能再次重新初始化。
To test my understanding, I have written the following small program. It seems as if I have actually succeeded in reassigning a reference. Can someone explain to me what is actually going on in my program?
为了测试我的理解,我编写了以下小程序。好像我真的成功地重新分配了一个参考。有人可以向我解释我的程序中实际发生了什么吗?
#include <iostream>
#include <stdio.h>
#include <conio.h>
using namespace std;
int main()
{
int i = 5, j = 9;
int &ri = i;
cout << " ri is : " << ri <<"\n";
i = 10;
cout << " ri is : " << ri << "\n";
ri = j; // >>> Is this not reassigning the reference? <<<
cout << " ri is : " << ri <<"\n";
getch();
return 0;
}
The code compiles fine and the output is as I expect:
代码编译正常,输出如我所料:
ri is : 5
ri is : 10
ri is : 9
回答by Useless
ri = j; // >>> Is this not reassigning the reference? <<<
ri = j; // >>> Is this not reassigning the reference? <<<
No, ri
is still a reference to i
- you can prove this by printing &ri
and &i
and seeing they're the same address.
没有,ri
仍然是一个参考i
-您可以通过打印证明这一点&ri
和&i
,看到他们是同一个地址。
What you did is modify i
throughthe reference ri
. Print i
after, and you'll see this.
您所做的是i
通过参考进行修改ri
。i
之后打印,你会看到这个。
Also, for comparison, if you create a const int &cri = i;
it won't let you assign to that.
此外,为了进行比较,如果您创建一个,const int &cri = i;
它不会让您分配给它。
回答by iammilind
It seems as if I have actually succeeded in reassigning a reference. Is that true?
好像我真的成功地重新分配了一个参考。真的吗?
No, you haven't. You are actually reassigning the value, and you are not rebinding the reference.
不,你没有。您实际上是在重新分配值,而不是重新绑定引用。
In your example, when you do int &ri = i;
, ri
is bound to i
for its lifetime. When you do ri = j;
, you are simply assigning the value of j
to ri
. ri
still remains a reference to i
! And it results in the same outcome as if you had instead written i = j;
在您的示例中,当您这样做时int &ri = i;
, ,ri
必然会i
持续其一生。当您这样做时ri = j;
,您只是将值分配给j
to ri
。ri
仍然是一个参考i
!它的结果与你写的结果相同i = j;
If you understand pointers well, then always think of the reference as an analogical interpretation of T* const
where T
is any type.
如果您很好地理解指针,那么请始终将引用视为T* const
where T
is any 类型的类比解释。
回答by sharptooth
When you assign something to a reference you actually assign the value to the object the reference is bound to. So this:
当您将某些内容分配给引用时,您实际上将值分配给了引用绑定到的对象。所以这:
ri=j;
has the same effect as
具有相同的效果
i = j;
would have because ri
is bound to i
. So any action on ri
is executed on i
.
会有因为ri
是必然的i
。所以任何 on 的动作ri
都是在上执行的i
。
回答by Eric Fortin
You are not reassigning the reference when executing ri = j;
. You're actually assigning j
to i
. Try printing i
after the line and you'll see that i
changed value.
执行时您不会重新分配引用ri = j;
。你实际上是分配j
给i
. 尝试i
在该行之后打印,您将看到i
更改后的值。
回答by Jan
OP asked for altering the referenced object through assignment to the reference and was very correctly told that this changed the reference object, not the reference. Now I did a more poignant attempt at really changing the reference and found potentially nasty stuff. First the code. It attempts to reassign to the reference var a newly created object, then alters the reference aka referenced object, finds that this is not reflected in the apparently referenced objects and concludes that we may have a case of a dangling pointer in C++. Sorry for the hastily composed code.
OP 要求通过对引用的赋值来更改引用的对象,并且被非常正确地告知这更改了引用对象,而不是引用。现在我做了一个更尖锐的尝试来真正改变参考并发现了潜在的令人讨厌的东西。先上代码。它尝试将新创建的对象重新分配给引用 var,然后更改引用又名被引用对象,发现这并未反映在明显引用的对象中,并得出结论,我们可能在 C++ 中遇到了悬空指针的情况。很抱歉匆忙编写的代码。
using namespace std;
vector<int>myints;
auto &i = myints.emplace_back(); // allocate and reference new int in vector
auto myintsaddr = &myints; auto myintfrontaddr = &myints.front(); // for future reference
i = 1; // assign a value to the new int through reference
cout << hex << "address of i: 0x" << &i << " equals " << "address of
myints.back(): 0x" << &myints.back() << '.' << endl; // check reference as expected
i = myints.emplace_back(); // allocate new int in vector and assign to old reference variable
i = 2; // give another value to i
cout << "i=" << i << ", myints={" << myints[0] << ", "<< myints[1] << '}' << endl; // any change to potentially referenced objects?
cout << hex << "&i: 0x" << &i << " unequal to " << "&myints.back(): 0x" << &myints.back() << " as well as &myints.front(): 0x" << &myints.front() << endl;
cout << "Myints " << (myintsaddr== &myints?"not ":"") << "relocated from " << myintsaddr << " to " << &myints << endl;
cout << "Myints front() " << (myintfrontaddr == &myints.front() ? "not " : "") << "relocated from " << myintfrontaddr << " to " << &myints.front() << endl;
Output:
输出:
address of i: 0x0063C1A0 equals address of myints.back(): 0x0063C1A0.
i=2, myints={1, 0}
&i: 0x0063C1A0 unequal to &myints.back(): 0x0063F00C as well as &myints.front(): 0x0063F008
Myints not relocated from 0039FE48 to 0039FE48
Myints front() relocated from 0063C1A0 to 0063F008
Conclusion: at least in my case (VS2017) the reference has kept the exact same address in memory, but the referenced values (part of the vector) have been reallocated elsewhere. Reference i may be dangling.
结论:至少在我的情况下(VS2017),引用在内存中保留了完全相同的地址,但引用的值(向量的一部分)已在其他地方重新分配。参考我可能悬而未决。
回答by Sid
You cannot "reseat" a reference(https://isocpp.org/wiki/faq/references#reseating-refs).
您不能“重新安装”参考(https://isocpp.org/wiki/faq/references#reseating-refs)。
One useful mantra with references in C++ is that the references arethe object they refer to. Any change you make to it isto make change to what ever they refer to. Using the mantra you can probably see what's happening when you do ri = j
, i now isj.
在C ++的引用的一个有用的咒语的是,参考文献是它们引用的对象。您对其所做的任何更改都是对其所指的内容进行更改。使用咒语,您可能会看到当您这样做时发生了什么ri = j
,我现在是j。