如何从引用中获取指针?

Oli*_*ver 54 c++

似乎有许多关于指针与参考的相关问题,但我找不到我想知道的东西.基本上,一个对象通过引用传入:

funcA(MyObject &objRef) { ... }
Run Code Online (Sandbox Code Playgroud)

在函数中,我可以获得指向该对象而不是引用的指针吗?如果我将引用objRef视为别名MyObject,&objRef实际上会给我一个指向MyObject的指针吗?这似乎不太可能.我很迷惑.

编辑:经过仔细检查,objRef确实给了我指向我需要的对象的指针 - 大多数人给了我正确的信息/答案,非常感谢.在这种情况下,我提出了似乎最具说明性的答案.

Pra*_*ian 93

是的,将address-of运算符应用于引用与获取原始对象的地址相同.

#include <iostream>

struct foo {};

void bar( const foo& obj )
{
  std::cout << &obj << std::endl;
}

int main()
{
  foo obj;
  std::cout << &obj << std::endl;
  bar( obj );

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

结果:

0x22ff1f
0x22ff1f
Run Code Online (Sandbox Code Playgroud)

  • 这不是"参考地址".是的,引用可能占用内存中的空间,因此有一个地址,但没有类型安全的方法来查找它. (3认同)

Jos*_*eld 33

应用于引用的任何运算符实际上将应用于它引用的对象(§5/ 5 [expr]); 引用可以被认为是同一对象的另一个名称.因此,获取引用的地址将为您提供它所引用的对象的地址.

实际上未指定引用是否需要存储(§8.3.2/ 4 [dcl.ref]),因此获取引用本身的地址是没有意义的.

举个例子:

int x = 5;
int& y = x;
int* xp = &x;
int* yp = &y;
Run Code Online (Sandbox Code Playgroud)

在上面的例子中,xpyp是相等的 - 也就是说,表达式的xp == yp计算结果是true因为它们都指向同一个对象.

  • 引用不仅仅是同一对象的另一个名称(引用的生命周期与它指向的对象的生命周期不同).但是,您的示例代码将起作用,因为在引用上使用任何运算符实际上都使用目标对象. (5认同)
  • @Ben:是的我总是发现单方面的论点(博客)是了解真相的最好方法.你自己说,引用是别名.别名=>'另一个名字'.是.完全合法的代码仍然可能导致未定义的行为.我所说的是有效的代码(即不调用未定义的行为)引用的持续时间不会长于它引用的对象,并且作为对象的另一个名称.你是说:当我们调用未定义的行为时,引用的行为就像一个指针.我说是的,那是什么. (3认同)
  • @Loki:我在同一个位置用另一个`int`替换`int`,没问题.显然它是一个新对象(析构函数运行旧对象,构造函数运行新对象).标准还说这是一个新的对象.我无法看到你的新发现的方法(取代现在失败的未定义行为的主张)完全没有任何意义,因为它完全消除了"对象生命周期"一词的任何含义.看起来更像是一种绝望的尝试,可以原谅你对我的评论和例子的反复攻击. (2认同)
  • 同意。对于将来遇到这种情况并感到好奇的任何人,我只想指出 § 3.8.1 (**[basic.life]/1**) 明确指出对于“T”类型的对象,它的生命周期开始于“获得类型‘T’具有正确对齐和大小的存储,并且如果该对象具有重要的初始化,则其初始化完成。”,并且它的生命周期结束于“如果‘T’是具有非平凡析构函数(12.4)的类类型,析构函数调用开始,或者对象占用的存储被重用或释放。” (根据 C++14 标准。) (2认同)

Ker*_* SB 25

一般的解决方案是使用std::addressof,如:

#include <type_traits>

void foo(T & x)
{
    T * p = std::addressof(x);
}
Run Code Online (Sandbox Code Playgroud)

无论是否T重载,这都有效operator&.

  • 极好的一点是,由于引用_是_引用的对象,因此需要小心,如果所述对象可能会重载`operator &amp;`...很少见,但对于代理类来说非常宝贵...有一天我会在需要它的地方恢复该项目! (2认同)

Dre*_*ann 7

在引用上使用地址运算符。

MyObject *ptr = &objRef;
Run Code Online (Sandbox Code Playgroud)


Ben*_*igt 6

&在引用上使用address-of()运算符.

&objRef
Run Code Online (Sandbox Code Playgroud)

与引用中使用的任何其他运算符一样,这​​实际上会影响引用的对象.

正如@Kerrek指出的那样,由于运算符会影响引用的对象,如果该对象具有重载operator&函数,则会调用它std::address_of来获取真实地址.