zoukankan      html  css  js  c++  java
  • [翻译]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 

  • 相关阅读:
    集合 排序 判断元素相等 [MD]
    软键盘 输入法管理器 InputMethodManager
    VideoView 视频播放 示例
    富文本 Htmll类 html标签
    MediaPlayer+SurfaceView 视频播放 示例
    SoundPool 音频播放 详解 示例
    MediaPlayer 音频播放 示例
    Strategy 策略模式 MD
    Chain of Responsibility 责任链模式 [MD]
    Iterator 迭代器模式 [MD]
  • 原文地址:https://www.cnblogs.com/shawnhue/p/More_CPP_Idioms_Address_Of.html
Copyright © 2011-2022 走看看