[翻译]More C++ Idioms - 取址器(Address of)

目的

找到一个一元&运算符被重载的对象的地址。

别称

 

动机

C++允许针对类重载一元&运算符,被重载的一元&运算符的返回值类型不需要是实际的对象地址。 虽然这样一个类的目的非常值得质疑,但是语言本身是允许这样做的。取址器(Address-of)惯用法是一种可以不用理会被重载的一元&运算符和它的可访问性而取得对象真实地址的方法。

在下面的例子中,main函数因为nonaddressable类的&运算符是私有的而不能通过编译。即使该运算符是可以被访问到的,一个从它的返回值类型double到指针的转换也是不可能或者说无意义的。

class nonaddressable 
{
public:
    typedef double useless_type;
private:
    useless_type operator&() const;
};
 
int main(void)
{
  nonaddressable na;
  nonaddressable * naptr = &na; // Compiler error here.
 
  return 0;

解决方案与示例代码

取址器(Address-of)惯用法通过一系列的转换来获得对象的地址。

template <class T>
T * addressof(T & v)
{
  return reinterpret_cast<T *>(& const_cast<char&>(reinterpret_cast<const volatile char &>(v)));
}
int main(void)
{
  nonaddressable na;
  nonaddressable * naptr = addressof(na); // No more compiler error.
 
  return 0;

 

 (译注:原文没有提到该实现的原理。这篇博客有原理介绍:http://blog.csdn.net/demon__hunter/article/details/5450498。但是里面没有详细说明为什么没有用reinterpret_cast<T *>(& reinterpret_cast<char &>(v))这样一重的转换,这里就补充说明一下:当 nonaddressable的类型被声明为const或者volatile时,前面的转换将会失败。因为reinterpret_cast是不能去除(但是可以加上)这两个属性的,const_cast虽然能去除,但是不能进行任意类型的强制转换。所以惯用法中首先通过reinterpret_cast将其转成const volatile的char类型,再用const_cast去掉const volatile的属性

已知应用

Boost addressof utility 

相关惯用法

 

参考资料

 

原文链接

http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Address_Of 

 

posted @ 2011-11-30 23:48  Shawnone  阅读(406)  评论(0编辑  收藏