boost 技术剖析: dynamic_bitset 与 proxy reference

原创 2007年10月01日 17:35:00
先给出 dynamic_bitset 的一个简单示例, 以增加感性认识:
    boost::dynamic_bitset<> a(2);
    a[0] = true;
    a[1] = false;
    if (a[0])
        std::cout << "a[0] holds true/n";

技术要点一: operator[ ] 返回了什么
    返回了引用. 举例来说,
    int a[2];
    a[1] = 3;
    if (a[1] == 4)
       //...
则前者 a[1] = 3 实际上相当于
    int& ra = *(a + 1);
    ra = 3;
后者则相当于
    if (ra == 4)
       //...
所以如果我们要正确重载 operator[ ] , 就也应该返回相应数据的引用, 这一点可以参考std::vector 的实现.

技术要点二: proxy reference
    在 dynamic_bitset 中,显然我们无法返回一个 "bit 引用", 怎么办? 我们做出一个与 "bit 引用"具有相同功能的数据类型. 首先,我们要看看 dynamic_bitset 的内部数据存储, 假设模板参数是unsigned int, 则下面是简化版:
    class dynamic_bitset
    {
       std::vector<unsigned int> m_bits;
       size_type   m_num_bits;
       // ...
    };
    以示例中的 a[1] = false 为例, 我们要引用的是 m_bits 中的第 1 个 unsigned int 的第 2 位, 因此我们的这个冒牌的 reference 看起来应该如下:
    class bit_reference
    {
       unsigned int& m_block;      // 引用第 1 个 unsigned int
       int   m_bit;            // 引用第 1 个 unsigned int 的第 2 位
    public:
       bit_reference(unsigned int& block, int bit)
       : m_block(block), m_bit(bit)
       {}
    };
因为是引用, 我们就应该有能力修改被引用的数据, 所以要紧紧抓住被引用的数据, 这就有了 m_block, 但是我们仅仅引用其中的一位(bit), 所以要记住这一位的位置.
    一般的"reference" 最重要的用处应该有两点: 1.存数据, 2.取数据, 而那个"bit 引用",虽然不存在,但也要求具有这两项功能: 1.存一个bool, 2.取一个 bool. 所以这个 bit_reference 要实现这两点:
    class bit_reference
    {
       // ...
       // 存 bool
       bit_reference& operator=(bool x)   {
          if (x)
             m_block |= (1 << m_bit);
          else
             m_block &= ~(1 << m_bit);
             return *this;
       }

       // 取 bool
       operator bool() const {
          return (m_block & (1 << m_bit) ) != 0;
       }

    有了这个"位引用", 我们就可以在 dynamic_bitset 中用上它了:
    class dynamic_bitset
    {
    // ...
    public:
        bit_reference operator[ ](size_type pos) {
          int nBlock = pos / sizeof(unsigned int);
          int nBit = pos % sizeof(unsigned int);
          return bit_reference(m_bits[nBlock], nBit);
       }
    到现在, 这个冒牌的reference基本上达到了我们的要求, 而且这个 dynamic_bitset 也基本上可以跑起来了,下面我们看看运行的过程, 以最前面的示例为例:
    1. a[0] = true
       调用过程为:
          bit_reference dynamic_bitset::operator[ ](0);
          bit_reference& bit_reference::operator=(bool x);
    2. if (a[1])
       调用过程为:
          bit_reference dynamic_bitset::operator[ ](1);
          bit_reference::operator bool ();

这个 bit_reference 就是我们所说的 proxy reference. 当我们无法实现原有数据类型的引用时, 我们就用另外一种数据类型来模仿这种引用, 而这种数据类型起码要实现两点: 存,取. 从广义上来说, STL 里面的 iterator 大多都是 proxy reference (除vector::iterator), 只是它们实现的功能在数据结构中都是显而易见的, 大家司空见惯了.

proxy reference 还有另外一个用处, 就是写时复制, 我们可以看到: 通过 proxy reference 我们只能从一个地方修改被引用的数据(以bit_reference 为例): bit_reference& operator=(bool x). 在这个函数里,我们就可以很容易地实现写时复制(copy on write). 在 <<The C++ Programming Language>>里有一个 string 类的写时复制实现, 使用的就是这种技术, 我们可以参考.

boost之dynamic_bitset

dynamic_bitset的使用#include #include #include #include #include using namespace std; using namesp...

How to make your Web Reference proxy URL dynamic

Introduction I have been asked before, how to make the URL property for a web reference to a web se...

2017 四川省赛 D.Dynamic Graph【拓扑排序+bitset优化】好题!

题面下载:https://icpc-camp-cdn.b0.upaiyun.com/permanent/problems/sichuan-2017.pdf 题目大意: 给你N个点,M条有向边,...

dynamic_bitset

C++标准为处理二进制数值提供了两个工具:vector和bitset. vector 是对元素类型为bool的vector特化,它内部并不真正存储bool值而是以bit来压缩保存,使用代理技术来操作b...

SpringIOC,DI+dynamic proxy 实现盗版AOP

  • 2015年12月08日 00:13
  • 29KB
  • 下载

Castle Dynamic Proxy代理使用

  • 2015年02月14日 10:12
  • 133KB
  • 下载

Java事务处理全解析(六)—— 使用动态代理(Dynamic Proxy)完成事务

在本系列的上一篇文章中,我们讲到了使用Template模式进行事务管理,这固然是一种很好的方法,但是不那么完美的地方在于我们依然需要在service层中编写和事务处理相关的代码,即我们需要在servi...

think in java笔记:Dynamic Proxy

think in java笔记:Dynamic Proxyproxy是什么? Proxy is one of the basic design patterns. It is an objec...

Java动态代理(Java Dynamic Proxy)

以下内容翻译自不知名的某个文档 概述 作为client和target之间的中间人(intermediary),代理在很多场合下是很有用的。 为了进一步理解动态代理的作用,我们首先看一个不使用代理机...

CGLib proxy dynamic

CGlib 是一个强大的, 高性能和高质量代码生成工具, 通常可以用它在运行期, 扩展已有Java代码类的功能或者实现某些接口; 并不能代理静态方法;JDK: 1.8 CGLib代码示例1 . 需要...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:boost 技术剖析: dynamic_bitset 与 proxy reference
举报原因:
原因补充:

(最多只允许输入30个字)