所以我正和朋友讨论参考和指针。
我们谈到的是"你可以拿一个指针的地址,但你不能拿一个参考地址"
我不同意这一点。举个例子:
int x = 0;
int &xRef = x;
cout << &xRef << &x <<endl;
此示例显示的是相同的地址,但从来没有通过xRef
获取&xRef
的地址。你不能说我们有两个具有相同地址的变量,所以即使我拿着引用的地址,它仍然是引用的地址(即使这是x的地址)?
答案 0 :(得分:9)
C ++标准版n3337 § 8.3.2 / 4
未指明引用是否需要存储(3.7)。
因此,未指定引用是否具有存储空间。很可能不是。这只是别名。当你在代码中使用它时,编译器会采取特殊操作,它可能会做一些类似于指针操作的事情。
答案 1 :(得分:4)
一元运算符&amp;返回指定对象的地址。参考不是一个对象。它是对象的引用。所以这句话
cout << &xRef << &x <<endl;
在两种情况下输出指定对象的地址x。即使编译器可以为引用分配内存,引用本身也没有地址这就是你不能应用operator&amp;得到它的地址。它是具有地址的引用引用的对象(或函数)。
答案 2 :(得分:2)
您可以将引用视为对象的别名。因此,在您的示例中,&xRef
声明xRef
x
的另一个名称。因此,您打印的是同一对象的地址的两倍。
答案 3 :(得分:0)
在您的示例中应用address-of运算符时,引用和实际对象之间不再有区别。 引用是对象。
规则改为在您尝试声明指向引用的指针时应用。试试吧:
int x = 0;
int &*ptr = &x;
MSVC 2013的结果:
error C2528: 'ptr' : pointer to reference is illegal
答案 4 :(得分:0)
为了完整起见:有一种方法可以生成指向引用的指针。
auto foo(int &x){
return [&]{std::cout << x;};
}
允许编译器在这里做的不是捕获对x
的引用,而是捕获堆栈指针。基于堆栈指针,编译器知道foo
的各种参数的偏移量,并且可以为lambda节省一些内存。但是,在返回lambda之后,foo
的参数消失了,lambda引用了不存在的对象。因此禁止/ UB这样做。