天天看點

C++實作的Buffer類

寫C#的同志一定覺得Byte []比C++的 BYTE * 加 Length的方式好的多。一來,隻需要一個對象就可以是表示一段位元組流,另一方面,由于C#的特性,不需要象C++那樣還要記得删除指針。由于我工作中,需要頻繁地試用C#和C++,是以寫了個C++的類,以便友善地管理位元組流。

  很簡單,先定義一個類:CMemoryBuffer。位元組流内部可以用std::vector<BYTE>來儲存,當然,考慮到效率,有些地方處理還是要考慮下。先把代碼貼出來,然後解釋為什麼這麼做。

  頭檔案:

#include <vector>       #include <queue>       #include <afxmt.h>       using namespace std;       class  CMemoryBuffer       {       public:           CMemoryBuffer(void);           CMemoryBuffer(const CMemoryBuffer &other);           CMemoryBuffer(const BYTE *tpBytes ,int tiLength);           virtual ~CMemoryBuffer(void);           //得到内部指針——const           const BYTE * c_Bytes() const;           //從内部拷貝資料到資料中           BYTE * CopyOut(int &tiLength) const;           //確定tppBytes指向的資料足夠大           void CopyTo(const BYTE ** tppBytes, int &tiLenth) const;           //從外部資料拷貝資料           void CopyFrom(const BYTE * tpBytes , int tiLength);           //從外部資料拷貝資料,添加           void Append(const BYTE * tpBytes , int tiLength);           void Append(const BYTE & tByte);           //從外部資料拷貝資料,插入           void Insert(int tiStartIndex,const BYTE * tpBytes , int tiLength);           CMemoryBuffer & operator = (const CMemoryBuffer &other);           CMemoryBuffer & operator += (const CMemoryBuffer &other);           const std::vector<BYTE> &GetBuffer() const { return m_vctBuffer; }           void Clear() ;           int GetLength() const { return (int)m_vctBuffer.size(); }           bool IsEmpty() const { return m_vctBuffer.size() == 0; }       public:           vector<BYTE> m_vctBuffer;       };      

CPP檔案:

#include "StdAfx.h"       #include "MemoryBuffer.h"       CMemoryBuffer::CMemoryBuffer(void)       {       }       CMemoryBuffer::~CMemoryBuffer(void)       {           this->Clear();       }       CMemoryBuffer::CMemoryBuffer(const CMemoryBuffer &other)       {           *this = other;       }       CMemoryBuffer::CMemoryBuffer(const BYTE *tpBytes ,int tiLength)       {           this->CopyFrom(tpBytes,tiLength);       }       void CMemoryBuffer::Clear()       {           vector<BYTE>().swap(this->m_vctBuffer);        }       const BYTE * CMemoryBuffer::c_Bytes() const       {           if(this->IsEmpty()) return NULL;           return &m_vctBuffer[0];       }       BYTE * CMemoryBuffer::CopyOut(int &tiLength) const       {           tiLength = this->GetLength();           if(this->IsEmpty()) return NULL;           BYTE *pBytes = new BYTE[tiLength];           memcpy(pBytes,&m_vctBuffer[0],tiLength);           return pBytes;       }       void CMemoryBuffer::CopyFrom(const BYTE * tpBytes , int tiLength)       {           this->Clear();           if(tpBytes == NULL || tiLength == 0) return;           m_vctBuffer.resize(tiLength,0);           memcpy(&m_vctBuffer[0],tpBytes,tiLength);       }       void CMemoryBuffer::Append(const BYTE * tpBytes , int tiLength)       {           if(tpBytes == NULL || tiLength == 0) return;           m_vctBuffer.resize(this->GetLength() + tiLength,0);           memcpy(&m_vctBuffer[0] + this->GetLength() - tiLength,tpBytes,tiLength);       }       void CMemoryBuffer::Append(const BYTE & tByte)       {           m_vctBuffer.push_back(tByte);       }       void CMemoryBuffer::Insert(int tiStartIndex,const BYTE * tpBytes , int tiLength)       {           if(tpBytes == NULL || tiLength == 0) return;           int iBufferSize = this->GetLength();           if(tiStartIndex > iBufferSize) return;           if(tiStartIndex == iBufferSize)           {               this->Append(tpBytes,tiLength);           }           else if((tiStartIndex + tiLength) < iBufferSize)           {               memcpy(&m_vctBuffer[0] + tiStartIndex,tpBytes,tiLength);           }           else           {               m_vctBuffer.resize(tiStartIndex + tiLength ,0);               memcpy(&m_vctBuffer[0] + tiStartIndex,tpBytes,tiLength);           }       }       void CMemoryBuffer::CopyTo(const BYTE ** tppBytes, int &tiLength)const       {           if(tppBytes == NULL || *tppBytes == NULL || this->IsEmpty()) return;           tiLength = this->GetLength();           memcpy(tppBytes,&m_vctBuffer[0],tiLength);       }       CMemoryBuffer & CMemoryBuffer::operator = (const CMemoryBuffer &other)       {           this->Clear();           if (!other.IsEmpty())           {               m_vctBuffer.insert(m_vctBuffer.begin(),other.GetBuffer().begin(),other.GetBuffer().end());           }           return *this;       }       CMemoryBuffer & CMemoryBuffer::operator += (const CMemoryBuffer &other)       {           if (!other.IsEmpty())           {               m_vctBuffer.insert(m_vctBuffer.end(),other.GetBuffer().begin(),other.GetBuffer().end());           }           return *this;       }      

解釋下幾點:

1、void CMemoryBuffer::Clear()

    {

     vector<BYTE>().swap(this->m_vctBuffer); 

    }

    這地方之是以要這麼寫,是因為vector有個毛病,clear後記憶體空間還不釋放,需要對象釋放後才釋放,如果頻繁操作一個大的位元組流,怕影響   記憶體性能.

2、void CMemoryBuffer::CopyFrom(const BYTE * tpBytes , int tiLength)

{

 this->Clear();

 if(tpBytes == NULL || tiLength == 0) return;

 m_vctBuffer.resize(tiLength,0);

 memcpy(&m_vctBuffer[0],tpBytes,tiLength);

}

    很多人可能會寫成一個循環語句:

    for(int i = 0; i < tiLength; i ++)

    m_vctBuffer.push_back(tpBytes[i]);

 這樣寫效率太低。

轉自 :

C++實作的Buffer類

C++實作的CMemoryStream類