2015-02-01 2 views
2

바이트의 비트를 직접 수정하려고합니다.클래스가있는 바이트의 비트 수정

GCC에서는 다음과 같이 작업을 수행 할 수 있습니다

struct virtualByte { 
    unsigned char b0 : 1; 
    unsigned char b1 : 1; 
    unsigned char b2 : 1; 
    unsigned char b3 : 1; 
    unsigned char b4 : 1; 
    unsigned char b5 : 1; 
    unsigned char b6 : 1; 
    unsigned char b7 : 1; 
} __attribute__((__packed__)); 

#define sbit(_byte, _pos) (((volatile struct virtualByte *)&_byte)->b ## _pos) 

사용법 :

unsigned char myByte = 0x00; 

#define firstBit sbit(myByte, 0) 

firstBit = 1; // Implicit myByte |= 0x01; 

이 일이 깔끔한 나는 나를 위해이 작업을 수행 클래스가 할 수 있도록하기를. 다음과 같은 개념을 생각해 냈습니다.

그러나 C++에서는 단일 비트에 대한 참조를 반환 할 수 없기 때문에이 방법은 작동하지 않습니다. 생성자를 오버로딩해도 작동하지 않습니다.

이러한 동작을 구현할 가능성이 있습니까? 대입 연산자는 기본 바이트 (바이트 집합이 아닌)를 직접 수정해야합니다.

+4

참조 C++의 ['bitset'] (http://en.cppreference.com/w/cpp/utility/bitset) – whoan

+0

C++의 비트셋이 있다는 것을 알고 있지만 바이트의 비트를 직접 수정하려고합니다. – d3L

+2

사이드 노트 : Big-Endian과 Little-Endian 아키텍처 간에는 첫 번째 방법이 이식 가능하지 않습니다. 지정된 컴파일러는 일반적으로 반대 방식으로 비트 필드 순서를 해석하기 때문입니다. –

답변

2

당신은 std::bitset를 사용하려면 :

std::bitset<12> someBits; // 12 bits 
someBits[0] = true; // set 1st bit 
std::cout << someBits.count() << '\n'; // prints 1 

std::bitset<12>::reference bit5 = someBits[5]; 
bit5 = true; 
std::cout << someBits.count() << '\n'; // prints 2 

당신은 당신이 원하는 방법으로 비트에 대한 참조를 반환 할 index operator를 사용할 수 있습니다. 이 참조는 bool&이 아니라 std::bitset::reference :

0

마지막으로 @doc 덕분에 많은 도움이되었습니다.

내 솔루션 :

class Bit { 
    private: 
     volatile uint8_t *byte; 
     uint8_t    bitPos; 

    public: 
     Bit(void) 
     { 
     } 

     void init(volatile uint8_t *const byte, uint8_t const bitPos) 
     { 
      this->byte  = byte; 
      this->bitPos = (bitPos > 7u ? 7u : bitPos); 
     } 

     void setValue(bool const bitValue) 
     { 
      if (!this->byte) return; 

      if (bitValue) { 
       *this->byte |= (1u << this->bitPos); 
      } else { 
       *this->byte &= ~(1u << this->bitPos); 
      } 
     } 
}; 

class BitReference { 
    private: 
     Bit   &ref; 

    public: 
     BitReference(Bit &ref) : ref(ref) 
     { 
     } 

     void operator=(bool const bitValue) 
     { 
      this->ref.setValue(bitValue); 
     } 
}; 

class Byte { 
    private: 
     Bit   bits[8]; 

    public: 
     Byte(volatile uint8_t *const byte) 
     { 
      for (unsigned i = 0; i < 8; ++i) { 
       this->bits[i].init(byte, i); 
      } 
     } 

     /* This did the trick :)! */ 
     BitReference operator[](size_t index) 
     { 
      if (index > 7) index = 7; 

      return BitReference(this->bits[index]); 
     } 
}; 

사용법 :

uint8_t myPort = 0x00; 

int main(int const argc, const char **const argv) 
{ 
    Byte abc(&myPort); 

    abc[0] = 1; 
    abc[1] = 1; 
    abc[2] = 1; 
    abc[3] = 1; 

    fprintf(stderr, "%2.2X\n", myPort); 

    return 0; 
} 
관련 문제