当我们创建对int 的引用时,我们无法重新分配对其他变量的引用,如下所示:
int a = 100;
int a1 = 200;
int &b = a;
&b = a1; // will get an error
但是,当我们创建一个指向的引用时,似乎可以将对指针的引用重新分配给其他指针(编译器在编译时不会检查),就像所以:
int main()
{
int* p;
int* p1;
int t = 100;
int t1 = 200;
int*& ref = p;
ref = &t;
*&ref = p1;
cout << p << endl;
cout << *p << endl;
cout << ref << endl;
*&ref = p1;
ref = &t1;
cout << p1 << endl;
cout << *p1 << endl; //segmentation fault
cout << ref << endl; //segmentation fault.
return 0;
}
我不明白为什么编译器会检查我们是否将引用重新分配给指向另一个指针的指针。这是g ++的设计方式还是我错过了一些概念?
答案 0 :(得分:3)
您不是重新分配引用(这是不可能的),而是更改引用引用的指针的值。
答案 1 :(得分:2)
之间没有区别
*&ref = p1;
和
ref = p1;
两者都将p1
1 中的地址复制到作为引用目标的指针中,既不会改变引用。并且不再与p1
建立关联,因此写ref = &t1;
不会分配给p1
。
特别是,&ref
等于&p
,因为引用是透明的。所有运算符都会影响指向的对象,不会影响引用本身。
(微妙的澄清,lambda capture-by-reference实际上可以捕获引用本身,而不仅仅是目标对象......但那不是运算符......如果它们是包含在内部结构中,并且在操作父结构时破坏了类型安全性,但是尝试覆盖引用会导致未定义的行为,您可以安全地从中读取所有行为)
1 由于p1
未初始化,因此复制它是未定义的行为。
答案 2 :(得分:1)
你的例子不是&#34;重新分配&#34;参考。
引用是指针。您的代码正在更改所引用指针的值。它不会更改引用,因此它引用不同的指针。
尝试声明
cout << p << ' ' << ref << endl;
你看他们都打印了相同的地址,因为ref已被初始化为对p的引用。无论何时分配p或ref,该值都会自然改变(例如&#34; p =&amp; some_variable&#34;或&#34; ref =&amp; some_other_variable&#34;)但两者将始终同步。
答案 3 :(得分:0)
正如其他人已经提到的,你没有重新绑定'ref'。你将绑定变量'p'指向的地址指向'p1',然后指向t1。
p1并且仍然未初始化,因此cout&lt;&lt; * p1&lt;&lt; endl是解除引用和未初始化的值(并且恰好有一个地址超出了你的内存空间)。