addressof

#include <iostream>
#include <boost/utility.hpp>

class codebreaker 
{ 
public: 
	int operator&() const { return 13; } 
};

int main(void)
{
	codebreaker A;
	//codebreaker *p = &A;					//error
	std::cout << &A << std::endl;
	std::cout<< boost::addressof(A) << std::endl;
	return 0;
}
/*
13
0015FDAB
请按任意键继续. . .
*/



    

addressof
头文件: "boost/utility.hpp"
要取得一个变量的地址,我们要依赖于返回的值是否真的是这个变量的地址。但是,技术上重载operator&是有可能的,这意味着存有恶意的人可以破坏你的地址相关的代码。boost::addressof 被用于获得变量的地址,不管取址操作符是否被误用。通过使用一些灵巧的内部机制,模板函数 addressof 确保可以获得真实的对象及其地址。

用法
为确保获得一个对象的真实地址,你要使用 boost::addressof. 它定义在 "boost/utility.hpp". 它常用于原本要使用 operator& 的地方,它接受一个参数,该参数为要获得地址的那个对象的引用。

#include "boost/utility.hpp"class some_class {};int main() {  some_class s;  some_class* p=boost::addressof(s);}
在进一步学习如何使用 addressof的细节前,了解一下operator&为何以及如何不一定会返回对象的地址是非常有用的。

快速了解一下存有恶意的人
如果你真的,真的,真的需要重载 operator&, 或者只是想试验一下操作符重载可能的用法,这的确很容易。当你重载 operator&时,它的语义肯定会与多数用户(以及函数!)所期望的不同,所以千万不要为了好玩而做这件事;除非有非常好的理由,否则不要去做它。以下有一段code-breaker代码:

class codebreaker {public:  int operator&() const {    return 13;  }};
对于这个类,任何人想获取一个codebreaker实例的地址都会得到一个不可思议的数字13.

template <typename T> void print_address(const T& t) {  std::cout << "Address: " << (&t) << '\n';}int main() {  codebreaker c;  print_address(c);}
这不难做到,但是在实际的代码中这样做有没有好的理由?也许没有,因为除非是用在局部的类上,否则它是不安全的。原因是,虽然获取一个不完整类型的地址是合法的,但如果是要获取一个带有用户自定义operator&的不完整类型的地址则是未定义的行为。因为我们不能保证这不会发生,所以我们最好不要重载 operator&.

迅速的解决方法
即使一个类的 operator& 被重载了,也还是有办法获得这个类的实例的真实地址。addressof 使用了一些幕后的巧妙方法[6]来获得真实的地址,而不会受任何 operator& 的欺骗。如果你把函数(print_address)改为使用 addressof, 你就可以得到以下代码:

[6] 非常出名的一种ingenious hack.

template <typename T> void print_address(const T& t) {  std::cout << "&t: " << (&t) << '\n';  std::cout << "addressof(t): " << boost::addressof(t) << '\n';}
执行时,该函数将给出如下输出(或类似于以下的输出,因为准确的地址值取决于你的系统).

&t: 13addressof(t): 0012FECB13
差不多就是这样了!如果有什么情况让你知道或怀疑一个类的operator&被重载了,而你又需要确保得到真实的地址(由于 operator& 被重载而变得不可信了), 你就应该使用 addressof.

总结
没有多少有力的论点支持重载 operator&,[7] 但由于这是可能的,总有些人会这样做。当你编写一些需要依赖于获得对象真实地址的代码时,addressof 可以帮助你确保得到真实的地址。在编写泛型代码时,没有办法知道将会操作什么类型,因此如果需要获取参数化类型的地址的话,就使用 addressof.

[7] 即使是定制的硬件设备驱动程序

当你需要获得一个对象的真实地址时,使用 addressof ,不必管 operator& 的语义。

  
    


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值