工作需要,写了个这样的类,不过仍需要不断改进
//BitSet.h
#include <wtypes.h>
class BitSet
{
public:
BitSet(void *pData,int nLenBytes);
~BitSet();
int GetLenth()const;
int operator[](int nIndex);
// int& operator[](int nIndex);
bool RestoreData(void *pData,int nlenBytes);
private:
void clean();
bool storedata(void *pData,int nLenBytes);
private:
BYTE *m_pData;
int m_nDataLenth;
};
//BitSet.cpp
#include "BitSet.h"
#include <stdio.h>
#include <stdexcept>
using namespace std;
BitSet::BitSet(void *pData,int nLenBytes)
{
m_pData = NULL;
m_nDataLenth = 0;
storedata(pData,nLenBytes);
}
BitSet::~BitSet()
{
clean();
}
void BitSet::clean()
{
if (m_pData)
{
delete []m_pData;
m_pData = NULL;
}
m_nDataLenth = 0;
}
int BitSet::GetLenth()const
{
return m_nDataLenth*8;
}
int BitSet::operator [](int nIndex)
{
int nEndIndex = 8*m_nDataLenth-1;
if ((nIndex <0) || (nIndex > nEndIndex))
{
throw out_of_range("out of range");
}
int nByteIndex = nIndex/8;
int nBitIndex = nIndex%8;
return (m_pData[nByteIndex]>>(7-nBitIndex))&0x01;
}
// int& BitSet::operator [](int nIndex)
// {
// int a = 23;
// return a;
// }
bool BitSet::storedata(void *pData,int nLenBytes)
{
clean();
if (pData)
{
m_pData = new BYTE[nLenBytes];
if (m_pData)
{
memcpy(m_pData,pData,nLenBytes);
m_nDataLenth = nLenBytes;
return true;
}
}
return false;
}
bool BitSet::RestoreData(void *pData,int nlenBytes)
{
return storedata(pData,nlenBytes);
}
int main()
{
int nTemp = 0xABCDABCD; //内存分布 CD(11001101) AB(10101011);
BitSet bset(&nTemp,sizeof(nTemp));
for (int i = 0;i<bset.GetLenth();++i)
{
printf("%d",bset[i]);
}
printf("\n");
return 0;
}
改进的地方是能够对具体位数据进行自由的赋值,即 operator[](int nIndex);,不过返回参数需要深思熟虑一下,需要一个中间过渡的类;
更新的内容:
1. 放弃了内存的拷贝,直接操作源数据,加快了运行速度;
2. 可以自由的对数据进行存取和修改,像操作数组一样;
改进后的代码如下
//BitSet.h
#include <wtypes.h>
// 期望BitSet拥有的功能:
// 对源数据进行操作而不是拷贝数据;
// 可以像使用数组一样对Bit进行访问和修改;
class VIRTUAL_INT
{
public:
VIRTUAL_INT(); //默认构造函数,BitSet有一个成员;
VIRTUAL_INT(BYTE*pData,int nOffset); //带参数的构造函数;
bool SetDataInfo(BYTE*pData,int nOffset); //重新设置成员;
int operator =(int); //支持 VIRTUAL_INT = value(int)操作;
VIRTUAL_INT operator=(VIRTUAL_INT); //支持 VIRTUAL_INT = VIRTUAL_INT操作;
operator int(); //支持VIRTUAL_INT->int 转换;
private:
BYTE * m_pData; //字节指针,仅仅指向一个字节(并且字节数组);
int m_nOffset; //Bit偏移,0->7是有效值;
};
class BitSet
{
public:
BitSet(void *pData);
~BitSet();
const int operator[](int nIndex)const;
VIRTUAL_INT& operator[](int nIndex);
bool RestoreData(void *pData);
private:
BYTE *m_pData;
VIRTUAL_INT m_VIRTUAL_INT;
};
//BitSet.cpp
#include "BitSet.h"
#include <stdexcept>
using namespace std;
VIRTUAL_INT::VIRTUAL_INT()
{
m_pData = NULL;
m_nOffset = 0;
}
VIRTUAL_INT::VIRTUAL_INT(BYTE*pData,int nOffset)
{
m_pData = pData;
if (nOffset >=0 && nOffset <8) //0->7;
{
m_nOffset = nOffset;
}
else
{
throw out_of_range("out of range of offset");
}
}
bool VIRTUAL_INT::SetDataInfo(BYTE*pData,int nOffset)
{
if (pData && nOffset >=0 && nOffset <8)
{
m_pData = pData;
m_nOffset = nOffset;
return true;
}
return false;
}
int VIRTUAL_INT::operator =(int Value)
{
if (Value != 0)
{
*(m_pData) |= (1<<(7-m_nOffset));
}
else
{
*(m_pData) &= ~(1<<(7-m_nOffset));
}
return Value;
}
VIRTUAL_INT VIRTUAL_INT::operator =(VIRTUAL_INT sValue)
{
int Value = (int)sValue;
operator=(Value);
return *this;
}
VIRTUAL_INT::operator int()
{
return ((*m_pData)>>(7-m_nOffset))&0x01;
}
BitSet::BitSet(void *pData)
{
if (pData)
{
m_pData = (BYTE*)pData;
}
}
BitSet::~BitSet()
{
m_pData = NULL;
}
const int BitSet::operator [](int nIndex)const
{
//printf("call []const\n");
if (nIndex <0)
{
throw out_of_range("out of range of index");
}
int nByteIndex = nIndex/8;
int nBitIndex = nIndex%8;
return (m_pData[nByteIndex]>>(7-nBitIndex))&0x01;
}
VIRTUAL_INT& BitSet::operator [](int nIndex)
{
// printf("call VIRTUAL_INT & []\n");
if (nIndex <0)
{
throw out_of_range("out of range of index");
}
int nByteIndex = nIndex/8;
int nBitIndex = nIndex%8;
m_VIRTUAL_INT.SetDataInfo(m_pData+nByteIndex,nBitIndex);
return m_VIRTUAL_INT;
}
bool BitSet::RestoreData(void *pData)
{
if(pData)
{
m_pData = (BYTE*)pData;
return true;
}
return false;
}
//Test.cpp
#include "BitSet.h"
#include <stdio.h>
int main()
{
BYTE bTemp = 0xAB; // 10101011
BitSet bset(&bTemp);
bset[0] = 0; //00101011
bset[1] = 5; //01101011;
bset[2] = bset[0]; //01001011;
bset[4] = bset[6] = bset[0]; //01000001;
int nTemp = bset[5]; //nTemp = 0;
if (bset[5] == 0)
{
bset[7] = 0; //01000000;
}
printf("%d-%d\n",(int)bset[0],bTemp); //0-64 在调用printf类似的函数时,bset[0]前面的(int)类型转换是必要的,后续会学习做到完美;
printf("end\n");
}