轉自 http://blog.csdn.net/athlong0564/article/details/5942351
寫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; };
#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]);
}
這樣寫效率太低.