权威网站有哪些,海口网络平台网站开发,wordpress评论头像,如何注册网站平台目录
1.引言
2.静态缓冲区
3.动态缓冲区
4.数据引用类
5.自动数据引用类
6.几种缓冲区的类关系图
7.注意事项
8.完整代码 1.引言 在C中#xff0c;设计静态和动态缓冲区类时#xff0c;需要考虑的主要差异在于内存管理的方式。静态缓冲区类通常使用固定大小的内存区域…目录
1.引言
2.静态缓冲区
3.动态缓冲区
4.数据引用类
5.自动数据引用类
6.几种缓冲区的类关系图
7.注意事项
8.完整代码 1.引言 在C中设计静态和动态缓冲区类时需要考虑的主要差异在于内存管理的方式。静态缓冲区类通常使用固定大小的内存区域即栈分配或静态分配而动态缓冲区类则根据需要动态地分配和释放内存即堆分配。下面将分别展示这几种缓冲区类的基本设计思路。 不管是静态缓冲区还是动态缓冲区都有统一的访问接口于是提取共用方法组成基础类
template class T
class CSimpleDataBufferBase : public CNoncopyable
{
public:typedef T DataType;typedef T* DataTypePointer;typedef T DataTypeReference;typedef const T ConstDataType;typedef const T* ConstDataTypePointer;typedef const T ConstDataTypeReference;public:CSimpleDataBufferBase() {}virtual ~CSimpleDataBufferBase() {}public:virtual DWORD GetSize() const 0;virtual DataTypePointer GetData() 0;virtual ConstDataTypePointer GetData() const 0;virtual DWORD GetMaxSize() const 0;operator DataTypePointer() { return GetData(); } DataTypeReference operator*() { return *GetData(); }DataTypeReference operator[](int nIndex);virtual BOOL SetData(ConstDataTypePointer pData, DWORD dwSize) 0;virtual void Clear() 0;
};
接口设计要点
1CSimpleDataBufferBase继承CNoncopyable禁止构造拷贝和赋值拷贝。
2访问缓冲区数据的接口const和非const版本。
3重载操作符*或[]访问缓冲区元素的数据
template class T
typename CSimpleDataBufferBaseT::DataTypeReference CSimpleDataBufferBaseT::operator[](int nIndex)
{if ( (nIndex 0) (nIndex (int)GetSize())){DataTypePointer pData GetData();return pData[nIndex];}else{throw std::out_of_range(invalid datanIndex position);}
}
4往缓冲区写数据接口接收的是const T*和数据的长度。
5获取缓冲区的上限。
5清空缓冲区。
2.静态缓冲区 静态缓冲区类通常包含一个固定大小的数组或其他容器但数组是最直接的例子并提供一系列方法来操作这个数组。 静态缓冲区类CStaticSimpleDataBufferT实现代码如下
//数据静态分配
template class T
class CStaticSimpleDataBufferT : public CSimpleDataBufferBaseT
{
public:CStaticSimpleDataBufferT(DWORD dwMaxSize MAX_STATIC_SIMPLE_BUFFER_SIZE);virtual ~CStaticSimpleDataBufferT() { }public:DWORD GetSize() const { return m_dwDataLen; }DataTypePointer GetData() { return m_sData ;}ConstDataTypePointer GetData() const { return m_sData ;}BOOL SetData(ConstDataTypePointer pData, DWORD dwSize);DWORD GetMaxSize() const { return m_dwMaxDataSize; }void Clear() { m_dwDataLen 0; }private:DataType m_sData[MAX_STATIC_SIMPLE_BUFFER_SIZE];DWORD m_dwDataLen;const DWORD m_dwMaxDataSize;
}; 从实现的代码看静态缓冲区就是在内存中事先分配好一段空间这种分配一般是在栈中进行分配速度特别快但是不灵活不能按照用户的大小需求分配空间。
3.动态缓冲区 动态缓冲区类通常基于动态内存分配如new和delete)来满足用户的需求。静态缓冲区的大小在编译时确定而动态缓冲区的大小则根据需要动态变化。静态缓冲区适用于那些大小已知且不会改变的场景而动态缓冲区则更灵活适用于大小可能变化的场景。动态缓冲区类CDynamicSimpleDataBufferT实现代码如下
//CSimpleDataBufferBase的默认适配器
template class T
class CSimpleDataBufferAdapter : public CSimpleDataBufferBaseT
{
public:CSimpleDataBufferAdapter() : m_pData(NULL),m_dwDataLen(0) { }virtual ~CSimpleDataBufferAdapter() { }public:DWORD GetSize() const { return m_dwDataLen; }BOOL SetData(ConstDataTypePointer pData, DWORD dwSize) { assert(0); return FALSE; }void SetSize(DWORD dwSize) { m_dwDataLen dwSize; }DWORD GetMaxSize() const { assert(0); return 0; }void Clear() { assert(0); }DataTypePointer GetData() { return m_pData ;}ConstDataTypePointer GetData() const { return m_pData ;}protected:DataTypePointer m_pData;DWORD m_dwDataLen;
};/动态缓冲区
template class T
class CDynamicSimpleDataBufferT : public CSimpleDataBufferAdapterT
{
public:CDynamicSimpleDataBufferT(DWORD dwMaxSize MAX_DYNAMIC_SIMPLE_BUFFER_SIZE);virtual ~CDynamicSimpleDataBufferT() { ClearData(); }public:void Clear() { m_dwDataLen 0; }DWORD GetMaxSize() const { return m_dwMaxDataSize; }BOOL SetData(ConstDataTypePointer pData, DWORD dwSize);protected:void ClearData();private:const DWORD m_dwMaxDataSize;
};
构造函数、析构函数、赋值函数实现如下
//构造函数
template class T
CDynamicSimpleDataBufferTT::CDynamicSimpleDataBufferT(DWORD dwMaxSize)
: m_dwMaxDataSize(dwMaxSize)
{m_pData new T[dwMaxSize];if (m_pData NULL)throw std:: bad_alloc(new T Array Failed);m_dwDataLen 0;assert(m_pData ! NULL);assert(m_dwDataLen 0);
}//清空数据函数
template class T
void CDynamicSimpleDataBufferTT::ClearData()
{if (m_pData)delete []m_pData;m_pData NULL;m_dwDataLen 0;
}//赋值函数
template class T
BOOL CDynamicSimpleDataBufferTT::SetData(ConstDataTypePointer pData, DWORD dwSize)
{int i;if (dwSize m_dwMaxDataSize)return FALSE;for (i 0; i (int)dwSize; i)m_pData[i] pData[i];m_dwDataLen dwSize;return TRUE;
} 析构函数自动调用了Clear函数释放了内存这样就不怕退出的时候出现内存泄漏。
4.数据引用类 在前面讲解的静态缓冲区和动态缓冲区内部都需要开辟空间而数据引用类不需要开辟空间CRefSimpleDataBufferT的具体实现如下
template class T
class CRefSimpleDataBufferT : public CSimpleDataBufferAdapterT
{
public:CRefSimpleDataBufferT() { }CRefSimpleDataBufferT(ConstDataTypePointer pBuffer, DWORD dwSize);virtual ~CRefSimpleDataBufferT() { }public:BOOL SetData(ConstDataTypePointer pBuffer, DWORD dwSize);void Clear();
};template class T
CRefSimpleDataBufferTT::CRefSimpleDataBufferT(ConstDataTypePointer pBuffer, DWORD dwSize)
{m_pData const_castDataTypePointer(pBuffer);m_dwDataLen dwSize;
}template class T
void CRefSimpleDataBufferTT::Clear()
{if (m_pData)delete []m_pData;m_pData NULL;m_dwDataLen 0;
}template class T
BOOL CRefSimpleDataBufferTT::SetData(typename CRefSimpleDataBufferTT::ConstDataTypePointer pBuffer, DWORD dwSize)
{Clear();m_pData const_castDataTypePointer(pBuffer);m_dwDataLen dwSize;return TRUE;
}
从实现的代码来看如果引用的数据是动态分配的就可以调用Clear函数释放内存反之则不需要调用。
5.自动数据引用类
自动数据引用类就是引用外部的动态分配的数据源并自动释放这个数据源的内存。CAutoRefSimpleDataBufferT的实现代码如下
//自动释放动态分配的数据引用类
template class T
class CAutoRefSimpleDataBufferT : public CRefSimpleDataBufferTT
{
public:CAutoRefSimpleDataBufferT() { }CAutoRefSimpleDataBufferT(ConstDataTypePointer pBuffer, DWORD dwSize);CAutoRefSimpleDataBufferT(ConstDataTypePointer pBuffer);void Clear();DataTypePointer operator-() { return GetData(); }ConstDataTypePointer operator-() const { return GetData(); }virtual ~CAutoRefSimpleDataBufferT();
};template class T
CAutoRefSimpleDataBufferTT::CAutoRefSimpleDataBufferT(typename CAutoRefSimpleDataBufferTT::ConstDataTypePointer pBuffer, DWORD dwSize)
: CRefSimpleDataBufferTT(pBuffer, dwSize)
{
}template class T
CAutoRefSimpleDataBufferTT::CAutoRefSimpleDataBufferT(typename CAutoRefSimpleDataBufferTT::ConstDataTypePointer pBuffer)
: CRefSimpleDataBufferTT(pBuffer, 1)
{
}template class T
void CAutoRefSimpleDataBufferTT::Clear()
{if (1 m_dwDataLen)delete m_pData;elseCRefSimpleDataBufferTT::Clear();
}template class T
CAutoRefSimpleDataBufferTT::~CAutoRefSimpleDataBufferT()
{Clear();
}
CAutoRefSimpleDataBufferT和CRefSimpleDataBufferT的不同点就在于析构函数自动调用了Clear函数释放了数据源的内存。
6.几种缓冲区的类关系图 7.注意事项
1静态成员变量的初始化静态成员变量需要在类外进行初始化并且只能初始化一次。
2线程安全如果多个线程可能同时访问这个静态缓冲区你需要实现适当的同步机制来避免数据竞争和不一致。
3资源管理静态缓冲区在程序结束时自动销毁但如果你在其中存储了动态分配的资源如指针指向的堆内存你需要确保在程序结束前正确释放这些资源。
4性能考虑静态缓冲区大小固定如果缓冲区大小设置不当可能会导致频繁的内存溢出或内存浪费。
5并发访问在并发环境中如果多个线程可能同时写入或读取缓冲区需要考虑使用互斥锁如std::mutex来同步访问。
8.完整代码
Noncopyable.h
/*************************************************************************// 功能: 防止拷贝类// 备注: *************************************************************************/
#pragma onceclass CNoncopyable
{
public:CNoncopyable() {}~CNoncopyable() {}protected:CNoncopyable(const CNoncopyable src); //拷贝构造函数const CNoncopyable operator(const CNoncopyable src); //赋值函数
};
SimpleDataBuffer.h
#pragma once
#include Noncopyable.h
#include assert.h
#include new
#include stdexcept
using namespace std;#define MAX_STATIC_SIMPLE_BUFFER_SIZE (4*1024) //4K
#define MAX_DYNAMIC_SIMPLE_BUFFER_SIZE (800*1024) //800Ktemplate class T
class CSimpleDataBufferBase : public CNoncopyable
{
public:typedef T DataType;typedef T* DataTypePointer;typedef T DataTypeReference;typedef const T ConstDataType;typedef const T* ConstDataTypePointer;typedef const T ConstDataTypeReference;public:CSimpleDataBufferBase() {}virtual ~CSimpleDataBufferBase() {}public:virtual DWORD GetSize() const 0;virtual DataTypePointer GetData() 0;virtual ConstDataTypePointer GetData() const 0;virtual DWORD GetMaxSize() const 0;operator DataTypePointer() { return GetData(); } DataTypeReference operator*() { return *GetData(); }DataTypeReference operator[](int nIndex);virtual BOOL SetData(ConstDataTypePointer pData, DWORD dwSize) 0;virtual void SetSize(DWORD dwSize) 0;virtual void Clear() 0;
};template class T
typename CSimpleDataBufferBaseT::DataTypeReference CSimpleDataBufferBaseT::operator[](int nIndex)
{if ( (nIndex 0) (nIndex (int)GetSize())){DataTypePointer pData GetData();return pData[nIndex];}else{throw std::out_of_range(invalid datanIndex position);}
}//数据静态分配
template class T
class CStaticSimpleDataBufferT : public CSimpleDataBufferBaseT
{
public:CStaticSimpleDataBufferT(DWORD dwMaxSize MAX_STATIC_SIMPLE_BUFFER_SIZE);virtual ~CStaticSimpleDataBufferT() { }public:DWORD GetSize() const { return m_dwDataLen; }DataTypePointer GetData() { return m_sData ;}ConstDataTypePointer GetData() const { return m_sData ;}BOOL SetData(ConstDataTypePointer pData, DWORD dwSize);void SetSize(DWORD dwSize) { m_dwDataLen dwSize; }DWORD GetMaxSize() const { return m_dwMaxDataSize; }void Clear() { m_dwDataLen 0; }private:DataType m_sData[MAX_STATIC_SIMPLE_BUFFER_SIZE];DWORD m_dwDataLen;const DWORD m_dwMaxDataSize;
};template class T
CStaticSimpleDataBufferTT::CStaticSimpleDataBufferT(DWORD dwMaxSize)
: m_dwDataLen(0),m_dwMaxDataSize(dwMaxSize)
{
}template class T
BOOL CStaticSimpleDataBufferTT::SetData(ConstDataTypePointer pData, DWORD dwSize)
{int i;if (dwSize m_dwMaxDataSize)return FALSE;for (i 0; i (int)dwSize; i)m_sData[i] pData[i];m_dwDataLen dwSize;return TRUE;
}
///
template class T
class CSimpleDataBufferAdapter : public CSimpleDataBufferBaseT
{
public:CSimpleDataBufferAdapter() : m_pData(NULL),m_dwDataLen(0) { }virtual ~CSimpleDataBufferAdapter() { }public:DWORD GetSize() const { return m_dwDataLen; }BOOL SetData(ConstDataTypePointer pData, DWORD dwSize) { assert(0); return FALSE; }void SetSize(DWORD dwSize) { m_dwDataLen dwSize; }DWORD GetMaxSize() const { assert(0); return 0; }void Clear() { assert(0); }DataTypePointer GetData() { return m_pData ;}ConstDataTypePointer GetData() const { return m_pData ;}protected:DataTypePointer m_pData;DWORD m_dwDataLen;
};/
template class T
class CDynamicSimpleDataBufferT : public CSimpleDataBufferAdapterT
{
public:CDynamicSimpleDataBufferT(DWORD dwMaxSize MAX_DYNAMIC_SIMPLE_BUFFER_SIZE);virtual ~CDynamicSimpleDataBufferT() { ClearData(); }public:void Clear() { m_dwDataLen 0; }DWORD GetMaxSize() const { return m_dwMaxDataSize; }BOOL SetData(ConstDataTypePointer pData, DWORD dwSize);protected:void ClearData();private:const DWORD m_dwMaxDataSize;
};template class T
CDynamicSimpleDataBufferTT::CDynamicSimpleDataBufferT(DWORD dwMaxSize)
: m_dwMaxDataSize(dwMaxSize)
{m_pData new T[dwMaxSize];if (m_pData NULL)throw std:: bad_alloc(new T Array Failed);m_dwDataLen 0;assert(m_pData ! NULL);assert(m_dwDataLen 0);
}template class T
void CDynamicSimpleDataBufferTT::ClearData()
{if (m_pData)delete []m_pData;m_pData NULL;m_dwDataLen 0;
}template class T
BOOL CDynamicSimpleDataBufferTT::SetData(ConstDataTypePointer pData, DWORD dwSize)
{int i;if (dwSize m_dwMaxDataSize)return FALSE;for (i 0; i (int)dwSize; i)m_pData[i] pData[i];m_dwDataLen dwSize;return TRUE;
}
//
template class T
class CRefSimpleDataBufferT : public CSimpleDataBufferAdapterT
{
public:CRefSimpleDataBufferT() { }CRefSimpleDataBufferT(ConstDataTypePointer pBuffer, DWORD dwSize);virtual ~CRefSimpleDataBufferT() { }public:BOOL SetData(ConstDataTypePointer pBuffer, DWORD dwSize);void Clear();
};template class T
CRefSimpleDataBufferTT::CRefSimpleDataBufferT(ConstDataTypePointer pBuffer, DWORD dwSize)
{m_pData const_castDataTypePointer(pBuffer);m_dwDataLen dwSize;
}template class T
void CRefSimpleDataBufferTT::Clear()
{if (m_pData)delete []m_pData;m_pData NULL;m_dwDataLen 0;
}template class T
BOOL CRefSimpleDataBufferTT::SetData(typename CRefSimpleDataBufferTT::ConstDataTypePointer pBuffer, DWORD dwSize)
{Clear();m_pData const_castDataTypePointer(pBuffer);m_dwDataLen dwSize;return TRUE;
}//自动释放动态分配的数据引用类
template class T
class CAutoRefSimpleDataBufferT : public CRefSimpleDataBufferTT
{
public:CAutoRefSimpleDataBufferT() { }CAutoRefSimpleDataBufferT(ConstDataTypePointer pBuffer, DWORD dwSize);CAutoRefSimpleDataBufferT(ConstDataTypePointer pBuffer);void Clear();DataTypePointer operator-() { return GetData(); }ConstDataTypePointer operator-() const { return GetData(); }virtual ~CAutoRefSimpleDataBufferT();
};template class T
CAutoRefSimpleDataBufferTT::CAutoRefSimpleDataBufferT(typename CAutoRefSimpleDataBufferTT::ConstDataTypePointer pBuffer, DWORD dwSize)
: CRefSimpleDataBufferTT(pBuffer, dwSize)
{
}template class T
CAutoRefSimpleDataBufferTT::CAutoRefSimpleDataBufferT(typename CAutoRefSimpleDataBufferTT::ConstDataTypePointer pBuffer)
: CRefSimpleDataBufferTT(pBuffer, 1)
{
}template class T
void CAutoRefSimpleDataBufferTT::Clear()
{if (1 m_dwDataLen)delete m_pData;elseCRefSimpleDataBufferTT::Clear();
}template class T
CAutoRefSimpleDataBufferTT::~CAutoRefSimpleDataBufferT()
{Clear();
}