2013-02-11 99 views
38

如何决定在拍摄物体地址时是否需要addressof(x)而不是&x何时使用addressof(x)而不是&x?


好像问题是混乱,所以澄清是为了:

addressof显然绕过超载地址的运营商。 我已经意识到这一点。

我想知道的是:
我怎么知道那是我真正想做的事? (特别是当模板内等)

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

回答

52

当您必须使用std::addressof时。可悲的是,“当你必须”包括任何时候你正在使用模板代码,并且想将未知类型的变量TT&变成一个诚实的上帝指针指向该变量的内存。

因为C++委员会愚蠢地允许引用操作符的重载(很少合法用途),所以用户可以使用某种类型实例化模板,而不能使用引用操作符来获取实际指针至。 std::addressof是一种解决使用这种可疑C++功能的用户的方法,以便执行语言应该保证能够开始工作的内容。

简而言之,这是一个语言愚蠢的图书馆修复程序。如果您想确保用户不能破坏您的代码,请将其用于模板代码而不是&。如果您的用户可以信任不使用这种构思功能,那么您可以使用&

+4

+1最佳答案我到目前为止看到了,解释情况非常好。 – Mehrdad 2013-02-11 20:47:35

+1

我觉得有趣的是* * * * *期望*超载地址,'reference_wrapper',似乎没有... – Mehrdad 2013-02-11 21:04:39

+1

@Mehrdad:这并不让我吃惊; 'reference_wrapper'和'addressof'都来自Boost。 AKA:那些最了解超载操作员的危险的人。 – 2013-02-11 21:11:18

5

当你想知道对象的实际地址,而不是地址的operator&过载的结果,使用它。

+0

这不会破坏运营商超载的目的吗? – Mehrdad 2013-02-11 20:31:22

+0

@Mehrdad也许 - 但你可以选择是否要过载。 – nos 2013-02-11 20:32:19

+0

@Mehrdad如果你相信每个人都可以实现好的操作符。 – 2013-02-11 20:32:19

7

如果这是一个用户定义的类型,并且重载一元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 
} 

我知道这是不安全的。

+0

虽然它不完全击败重载运算符的目的吗?我怎么知道我是否应该打败它? – Mehrdad 2013-02-11 20:32:56

+0

@Mehrdad见编辑。 – 2013-02-11 20:34:37

+0

嗯,所以这是一种情况,我不能*甚至首先使用'&',这使得问题没有意义! – Mehrdad 2013-02-11 20:46:04

6

我唯一的意见:

除非你是团队设计类和接口的一部分,从来没有。我个人从来没有看到过载该操作员的好理由。但是如果有人设计了一个有意义的类,并且假定这个类是为公共消费而设计的(也就是说,这个类不仅仅用于特定的图书馆内部使用),我会期望这个类以正常的代码工作自然期望&的意思是“地址”。如果重载操作符的类不是以一种明智的方式设计的,那么我不会使用该类,句号。因为任何一个类都被破坏了,或者它并不打算在它所属的图书馆之外使用。

4

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

你绝对没有保证过载operator&是对象“的地址”,没准它是不是,还是类的作者可能不会打扰超载了。他们可能已经超载它返回一个不同的类型,或者如果他们不情愿地试图阻止人们使用它的地址,甚至可以返回void

如果你想有一个指针,该可能重载&的对象(例如,因为它的类型是一个模板参数,所以你不知道),那么无论是使用std::addressof或文档模板不支持该类型不要将对象的实际地址作为正确的类型返回。

相关问题