zoukankan      html  css  js  c++  java
  • 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类

  • 相关阅读:
    只需5分钟就能Get到的神器:Python虚拟环境安装&使用
    Linux——28年桌面进化史
    Linux使用Pidstat命令查看进程状态信息
    提高思维能力的书籍推荐你看这本《决策必读12篇》
    管理和自我管理:领导者自我管理的重要性
    带团队看什么书 ?这本书教你提升团队凝聚力
    基于RNN和CTC的语音识别模型,探索语境偏移解决之道
    详解Spring中Bean的作用域与生命周期
    物联网通信技术,那些你不知道的事
    一招教你数据仓库如何高效批量导入与更新数据
  • 原文地址:https://www.cnblogs.com/rainbow70626/p/8018683.html
Copyright © 2011-2022 走看看