2012-08-24 47 views
2

我正在爲我正在處理的GA事物放置一個bitarray類。我想知道是否有更好的方法來做我的[]操作員做任務比我想出的。現在,我有非const的操作符版本的值返回一個祕密的'bitsetter'類,這似乎有點過分。我當然不能通過引用返回,但我想知道是否有更好的(即更簡潔高效的)方法。提前致謝。請原諒我的throw 0。完全是一個佔位符;)自定義bitarray []和賦值運算符

class bitsetter 
{ 
public: 
    short ind; 
    unsigned char *l; 

    bitsetter & operator=(int val) 
    { 
     int vs = 1<<ind; 
     if(val==0) { 
      vs = ~vs; 
      *l = *l & vs; 
     } 
     else 
     { 
      *l = *l | vs; 
     } 
     return *this; 
    } 


    int value() const 
    { 
     return ((*l)>>ind)&1; 
    } 

    friend std::ostream & operator << (std::ostream & out, bitsetter const & b) 
    { 
     out << b.value(); 
     return out; 
    } 

    operator int() { return value(); } 
}; 

class bitarray 
{ 
public: 
    unsigned char *bits; 
    int size; 

    bitarray(size_t size) 
    { 
     this->size = size; 
     int bsize = (size%8==0)?((size+8)>>3):(size>>3); 
     bits = new unsigned char[bsize]; 
     for(int i=0; i<size>>3; ++i) 
      bits[i] = (unsigned char)0;   
    } 

    ~bitarray() 
    { 
     delete [] bits; 
    } 

    int operator[](int ind) const 
    { 
     if(ind >= 0 && ind < size) 
      return (bits[ind/8] >> (ind%8))&1; 
     else 
      return 0; 
    } 

    bitsetter operator[](int ind) 
    { 
     if(ind >= 0 && ind < size) 
     { 
      bitsetter b; 
      b.l = &bits[ind/8]; 
      b.ind = ind%8; 
      return b; 
     } 
     else 
      throw 0; 
    } 
}; 
+1

對我來說似乎很好。從我記得,這是Stroustrup推薦的方法。 –

回答

2

這是標準的做法,它被稱爲代理。請注意,它通常是在類本身中定義:

class bitfield 
{ 
public: 
    class bit 
    { }; 
}; 

此外,它保持多一點「安全」:

class bitfield 
{ 
public: 
    class bit 
    { 
    public: 
     // your public stuff 
    private: 
     bit(short ind, unsigned char* l) : 
     ind(ind), l(l) 
     {} 

     short ind; 
     unsigned char* l; 

     friend class bitfield; 
    }; 

    bit operator[](int ind) 
    { 
     if (ind >= 0 && ind < size) 
     { 
      return bit(&bits[ind/8], ind % 8); 
     } 
     else 
      throw std::out_of_range(); 
    } 
}; 

所以,人們只能看到位的公共接口,而不能召喚自己。