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類


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM