引用的地址

Address of a reference

本文关键字:地址 引用      更新时间:2023-10-16

所以我正在和一个朋友讨论关于引用和指针的问题。

我们讨论的是"你可以取一个指针的地址但你不能取一个引用的地址"

我不同意这一点。让我们举个例子:

int x = 0;
int &xRef = x;
cout << &xRef << &x <<endl;

这个例子显示了相同的地址,但我不是通过执行&xRef来获取xRef的地址。难道你不认为我们有两个具有相同地址的变量,所以即使我取的是引用的地址,它仍然是引用的地址(即使那是x的地址)?

c++标准n3337 § 8.3.2/4

未指定引用是否需要存储空间(3.7)。

所以这是未指定的引用是否有存储空间。很可能不会。它只是别名。当你在代码中使用它时,编译器会进行一些特殊的操作,它可能会做一些类似于指针操作的事情。

一元操作符&返回指定对象的地址。引用不是对象。它是对对象的引用。所以这个语句

cout << &xRef << &x <<endl;

在这两种情况下都输出属于x的指定对象的地址。尽管编译器可以为引用分配内存,但引用本身没有地址,也就是说你不能应用operator &来得到它的地址。它是由具有地址的引用所引用的对象(或函数)。

您可以将引用视为对象的别名。因此,在您的示例中,&xRef声明xRef,这是 x的另一个名称。因此,您打印了同一对象的两次地址。

当您在示例中应用地址操作符时,引用和实际对象之间不再存在区别。引用对象。

该规则只适用于试图声明指向引用的指针的时候。试一试:

int x = 0;
int &*ptr = &x;

结果与MSVC 2013:

error C2528: 'ptr' : pointer to reference is illegal

为了完整起见:有一种方法可以生成指向引用的指针。

auto foo(int &x){
    return [&]{std::cout << x;};
}

编译器在这里允许做的不是捕获对x的引用,而是捕获堆栈指针。基于堆栈指针,编译器知道foo的各种参数的偏移量,并可能为lambda节省一些内存。但是,在返回lambda之后,foo的参数消失了,并且lambda引用的对象不存在。因此,禁止/UB这样做