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的学习

c++标准为处理二进制数值提供了两个工具:vector和bitset。      vector是对元素类型为bool的vector特化,它的内部并不真正存储bool值,而是以bit来压缩保存、使用代...
  • ooooo12345re
  • ooooo12345re
  • 2016年06月09日 11:29
  • 1643

boost dynamic_bitset

dynamic_bitset:  c++98标准为处理二进制数值提供了两个工具:vector和bitset. vector是对元素类型为bool的vector特化,内部并不真正存储bool值,而是...
  • mmzsyx
  • mmzsyx
  • 2012年11月29日 16:45
  • 5552

boost::dynamic_bitset介绍 和STL bitset类似

bitset 与vector 类似,同样存储二进制位,但它的大小固定,而且比vector支持更多的位运算。 vector可以动态增长,但不能方便地进行位运算; bitset 则正好相反,可以方便地对...
  • u011676589
  • u011676589
  • 2013年08月31日 21:28
  • 1384

boost之dynamic_bitset

dynamic_bitset的使用#include #include #include #include #include using namespace std; using namesp...
  • qq_31839479
  • qq_31839479
  • 2017年01月02日 19:34
  • 673

【Boost】boost::dynamic_bitset介绍

bitset 与vector 类似,同样存储二进制位,但它的大小固定,而且比vector支持更多的位运算。 vector可以动态增长,但不能方便地进行位运算; bitset 则正好相反,可以方便地对...
  • huang_xw
  • huang_xw
  • 2012年12月29日 18:29
  • 7004

关于bitset和dynamic_bitset的使用问题!

     昨天程序中要使用大量的boo来表征对象是否被引用,我马上想到了std::bitset,但是仔细一看,bitset不是动态了,需要编译器制定个数的,而不是运行期的,我需要的是运行期的。    ...
  • jiaoshuchun
  • jiaoshuchun
  • 2009年07月03日 08:46
  • 1020

boost库中好用的bitset(位串)

// boost中的bitset// 太棒了#include #include #include int main(int argc, char* argv[]){ int n=32; b...
  • blackboyofsnp
  • blackboyofsnp
  • 2009年10月13日 19:05
  • 2963

C++ boost 组件简介:数据结构, 容器, 迭代器和算法

 数据结构, 容器, 迭代器, 和算法Boost.AnyAny库支持类型安全地存储和获取任意类型的值。当你需要一个可变的类型时,有三种可能的解决方案:无限制的类型,如 void*. 这种方法不可能是类...
  • hexiankun
  • hexiankun
  • 2008年11月10日 15:19
  • 2113

boost::dynamic_bitset

http://www.boost.org/doc/libs/1_55_0/libs/dynamic_bitset/dynamic_bitset.html The dynamic_bitset c...
  • aaashen
  • aaashen
  • 2014年03月12日 10:52
  • 472

记boost在gcc的一个库链接问题generic_category()

报错大致如下: main.cpp:(.text+0x49): undefined reference to `boost::system::generic_category()' main.cpp:(...
  • yuxiaohen
  • yuxiaohen
  • 2013年08月01日 23:30
  • 22030
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:boost 技术剖析: dynamic_bitset 与 proxy reference
举报原因:
原因补充:

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