我如何决定是否需要addressof(x)
而不是&x
在获取对象的地址时?
似乎这个问题令人困惑,因此需要澄清一下:
addressof
显然绕过了重载的地址运算符。我已经意识到这一点。
我想知道的是:
我怎么知道这是否是我真正想做的?(特别是在模板内等时)
是否有某种“规则”可以帮助我确定何时需要addressof
而不是&
?
毕竟,它们都返回对象的“地址”,那么我什么时候使用哪个呢?
必要时使用std::addressof
。可悲的是,“当你必须”包括任何时候你在模板代码中工作,并且想要将一个未知类型的变量T
转换T&
为一个指向该变量内存的诚实指针。
因为 C++ 委员会愚蠢地允许引用运算符的重载(几乎没有合法目的),所以用户可以用某种类型来实例化您的模板,而您不能使用引用运算符来获取实际的指针。std::addressof
是一种解决使用这种可疑 C++ 功能的用户的方法,以便执行该语言应该保证的工作。
简而言之,这是一个针对语言愚蠢的库修复。&
如果您想确保用户不会破坏您的代码,请在模板代码中使用它。如果可以信任您的用户不会使用这个考虑不周的功能,那么您可以使用&
.
如果它是重载 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
}
我知道这不安全。
当您想知道对象的实际地址而不是地址operator&
重载的结果时使用它。
仅我个人意见:
除非您是设计类及其接口的团队的一员,否则永远不要。我个人从未见过重载该运算符的充分理由。但是,如果有人设计了一个有意义的类,并假设该类是供公众使用的(也就是说,该类不仅仅在特定库中供内部使用),我希望该类可以在正常代码中工作那自然期望这&
意味着“地址”。如果重载运算符的类没有以如此明智的方式设计,那么我就不会使用那个类。因为该类要么被破坏,要么不打算在它所属的库之外使用。
毕竟,它们都返回对象的“地址”,那么我什么时候使用哪个呢?
您绝对不能保证重载operator&
是对象的“地址”,很可能不是,或者类作者可能不会费心重载它。他们本可以重载它以返回不同的类型,或者void
如果他们不明智地试图阻止人们获取其地址,甚至可以返回。
如果您想要一个指向可能已重载的对象的指针&
(例如,因为它的类型是模板参数所以您不知道),那么请使用std::addressof
或记录您的模板不支持不返回对象真实地址的类型作为正确的类型。