83

我如何决定是否需要addressof(x)而不是&x在获取对象的地址时?


似乎这个问题令人困惑,因此需要澄清一下:

addressof显然绕过了重载的地址运算符。我已经意识到这一点。

我想知道的是:
我怎么知道这是否是我真正想做的?(特别是在模板内等时)

是否有某种“规则”可以帮助我确定何时需要addressof而不是&
毕竟,它们都返回对象的“地址”,那么我什么时候使用哪个呢?

4

5 回答 5

120

必要时使用std::addressof。可悲的是,“当你必须”包括任何时候你在模板代码中工作,并且想要将一个未知类型的变量T转换T&为一个指向该变量内存的诚实指针。

因为 C++ 委员会愚蠢地允许引用运算符的重载(几乎没有合法目的),所以用户可以用某种类型来实例化您的模板,而您不能使用引用运算符来获取实际的指针。std::addressof是一种解决使用这种可疑 C++ 功能的用户的方法,以便执行该语言应该保证的工作。

简而言之,这是一个针对语言愚蠢的库修复。&如果您想确保用户不会破坏您的代码,请在模板代码中使用它。如果可以信任您的用户不会使用这个考虑不周的功能,那么您可以使用&.

于 2013-02-11T20:46:42.220 回答
16

如果它是重载 unary 的用户定义类型operator&,并且您想要它的地址,请使用addressof.

我会说你应该总是使用&,因为正如你所说,如果你不这样做,它就会破坏超载的目的。当然,除非你对重载做了一些有意义的事情,在这种情况下你需要addressof(在课堂之外,你可以在里面使用this),但你必须非常确定你在做什么。

这里还有更多——如果你想operator&在类外重载(你可以),你必须使用addressof返回地址,否则会导致无限递归:

struct Class
{
   virtual ~Class() {}
   int x;
};

void* operator&(const Class& x)
{
    //return &x; <---- infinite recursion
    return addressof(x) + 4; //I know this isn't safe
                             //but I also know the intrinsics of my compiler
                             //and platform to know this will actually return
                             //the address to the first data member
}

我知道这不安全。

于 2013-02-11T20:31:14.910 回答
9

当您想知道对象的实际地址而不是地址operator&重载的结果时使用它。

于 2013-02-11T20:31:02.807 回答
7

仅我个人意见:

除非您是设计类及其接口的团队的一员,否则永远不要。我个人从未见过重载该运算符的充分理由。但是,如果有人设计了一个有意义的类,并假设该类是供公众使用的(也就是说,该类不仅仅在特定库中供内部使用),我希望该类可以在正常代码中工作那自然期望这&意味着“地址”。如果重载运算符的类没有以如此明智的方式设计,那么我就不会使用那个类。因为该类要么被破坏,要么不打算在它所属的库之外使用。

于 2013-02-11T20:38:40.753 回答
6

毕竟,它们都返回对象的“地址”,那么我什么时候使用哪个呢?

您绝对不能保证重载operator&是对象的“地址”,很可能不是,或者类作者可能不会费心重载它。他们本可以重载它以返回不同的类型,或者void如果他们不明智地试图阻止人们获取其地址,甚至可以返回。

如果您想要一个指向可能已重载的对象的指针&(例如,因为它的类型是模板参数所以您不知道),那么请使用std::addressof或记录您的模板不支持不返回对象真实地址的类型作为正确的类型。

于 2013-02-11T21:34:58.710 回答