目的

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

别称

 

动机

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 

 

相关文章:

  • 2022-12-23
  • 2021-10-21
  • 2021-08-27
  • 2021-04-26
  • 2021-08-08
  • 2021-11-10
  • 2022-12-23
  • 2021-10-14
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2021-08-17
  • 2021-12-16
  • 2022-01-16
  • 2022-12-23
相关资源
相似解决方案