addressof

来源:互联网 发布:o2o网络借贷模式的特点 编辑:程序博客网 时间:2024/06/04 19:43
#include <iostream>#include <boost/utility.hpp>class codebreaker { public: int operator&() const { return 13; } };int main(void){codebreaker A;//codebreaker *p = &A;//errorstd::cout << &A << std::endl;std::cout<< boost::addressof(A) << std::endl;return 0;}/*130015FDAB请按任意键继续. . .*/



    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
原创粉丝点击