我们可以在C++中重新分配引用吗
Can we reassign the reference in C++?
我到处都读到引用必须立即初始化,不能再次初始化。
为了测试我的理解能力,我编写了以下小程序。我似乎真的成功地重新分配了一个推荐人。有人能向我解释一下我的节目到底发生了什么吗?
#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;
}
代码编译良好,输出如我所料:
ri is : 5
ri is : 10
ri is : 9
ri = j; // >>> Is this not reassigning the reference? <<<
不,ri
仍然是对i
的引用——您可以通过打印&ri
和&i
并看到它们是相同的地址来证明这一点。
您所做的是通过引用ri
来修改i
。之后打印i
,您就会看到这个。
此外,为了进行比较,如果您创建了一个const int &cri = i;
,它将不允许您分配给它。
我似乎真的成功地重新分配了一个推荐人。这是真的吗?
没有,你没有。您实际上是在重新分配值,而不是重新绑定引用。
在您的示例中,当执行int &ri = i;
时,ri
在其生存期内绑定到i
。执行ri = j;
时,只需将j
的值指定给ri
。ri
仍然是对i
的引用!它的结果与您编写i = j;
的结果相同
如果您很好地理解指针,那么请始终将引用视为对T* const
的类比解释,其中T
是任何类型。
当你给一个引用赋值时,你实际上是给引用绑定的对象赋值
ri=j;
具有与相同的效果
i = j;
因为CCD_ 21与CCD_。因此,对ri
的任何操作都在i
上执行。
您不能"重新设置"引用(https://isocpp.org/wiki/faq/references#reseating-参考文献)。
C++中引用的一个有用的咒语是引用是它们所指的对象。你对它所做的任何更改都是对它们所指内容的更改。使用这个咒语,你可能可以看到当你执行ri = j
时发生了什么,我现在就是j.
执行ri = j;
时不会重新分配引用。实际上,您正在将j
分配给i
。尝试在该行之后打印i
,您会看到i
更改了值。
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;
输出:
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
结论:至少在我的案例(VS2017)中,引用在内存中保持了完全相同的地址,但引用的值(向量的一部分)已被重新分配到其他地方。参考i可能是悬空的。
简单地说,
ri = j;
<-您正在x(ri)内存中写入j的值。并且ri仍然保持或指向x。
- 对具有动态分配的内存和析构函数的类对象的引用
- 拥有映射的现代方法,该映射可以指向或引用已在堆栈上分配的不同类型的数据
- 我如何通过引用将 c++ 字符串分配给另一个字符串
- 将引用分配给局部变量,如果局部变量超出范围,它会超出范围吗?
- 如何在构造函数中构造对象并分配引用
- C++中的可重新分配引用
- 如何分配引用链的末端
- c++ 在 if 语句中分配引用变量
- 为什么不能重新分配引用的目标对象?
- 阻止重新分配引用
- C++ 从传入的引用变量中分配引用变量
- C++可以重新分配引用
- 重新分配C++引用变量
- 有条件地分配引用
- 我们可以在C++中重新分配引用吗
- C++在为指针分配引用时获取临时错误的地址
- 为什么可以在 for 语句中重新分配引用常量
- 如何(优雅地)根据字符别名分配引用成员
- 处理赋值运算符重载;您可以重新分配引用吗?
- 对左值和右值的可分配引用