为了实现面向对象编程,对于的复杂型结构快速构造与释放,写了个内存池管理模板。他特点是允许用户放弃内存池生成对象使用权,而不是执行析构。实现对象的复用。
- 实现同类型对象的全局化管理。无需显示构造内存池。采用newOne宏申请对象。
- 内存块的大小可调。内存池状态可输出显示。
- 采用内存预分配方式。对象构造采用原始构造,非动态申请和复制构造,提高速度。
- 加锁,实现多线程支持。(加锁会额外耗费cpu时间,可设置宏
CLMP_USE_LOCK_TYPE
,决定采用哪种方案)
#define CLMP_USE_LOCK_TYPE 0 // 0=无锁(快),1=用C++锁(慢),2=用windows临界区锁
- 通过giveUpOne()方法,放弃对象使用权,不需要释放对象,实现快速对象复用。
演示代码:应用案例: 【C++高速矩阵类实现】.
//定义任意类型,其构造含有动态内存的申请。
struct MyStruct
{
int * c;
string name;
MyStruct(const char* lpName = "" )
:c(new int[100]) , name(lpName)
{
cout << "\nMyStruct 构造!: " << name << endl;
}
~MyStruct() {
delete[] c;
cout << "\nMyStruct 析构! " << name << endl;
}
};
int main() {
auto p1 = newOne(MyStruct,"p1"); //申请一个对象,命名未p1
giveUpOne(p1); //放弃使用权,不执行对象析构
auto p2 = newOne(MyStruct,"p2"); //申请第二个对象,命名未p2
if (p1 == p2) //由于giveUpOne调用,前后两次newOne产生复用
cout << "\np2 获得了复用对象: " << p2->name << endl;
auto p3 = newOne(MyStruct, "p3"); //再申请一个对象
// ...
//使用完成后释放对象,归还到内存池
deleteOne(p1); // 注意:此处应该避免继续使用p1,因为他意见显示放弃了使用权。
deleteOne(p2); // 因为p2与p1保存同一个对象指针,不会重复释放。
deleteOne(p3);
getchar();
return 1;
运行结果:
模板库头源码:
CLMemPool.h
//DESIGNED BY CAILUO @2020-02-10
//MINI-SUPPORT @ C++14
#pragma once
#ifndef __CL_MEMPOOL_H__
#define __CL_MEMPOOL_H__
#include <cassert>
#include <map>
#include <string>
#include <stdexcept>
#define CLMP_USE_LOCK_TYPE 0 // 0=无锁(快),1=用C++锁(慢),2=用windows临界区锁
#if CLMP_USE_LOCK_TYPE == 2
#include "windows.h" //windows平台,临界区
class CLLock {
private:
CRITICAL_SECTION cs;
public:
CLLock() {
InitializeCriticalSection(&cs); }
~CLLock() {
DeleteCriticalSection(&cs); }
void lock() {
EnterCriticalSection(&cs); }
void unlock() {
LeaveCriticalSection(&cs); }
};
#elif CLMP_USE_LOCK_TYPE == 1
#include <mutex> // C++ STL mutex
class CLLock {
private:
std::mutex mt;
public:
void lock() {
mt.lock(); }
void unlock() {
mt.unlock(); }
};
#else
class CLLock {
//no use lock, it do nothing
public:
void lock() {
}
void unlock() {
}
};
#endif
#ifndef _CL_DIFVARS_SUPPORT_
#define _CL_DIFVARS_SUPPORT_
#ifdef UNICODE
typedef wchar_t Char;
#define tstring wstring
#ifndef _T
#define _T(x) L ## x
#endif
#ifndef _tprintf_s
#define _tprintf_s wprintf_s
#define _stprintf_s swprintf_s
#define _tcscpy_s wcscpy_s
#endif
#else
typedef char Char;
#define tstring string
#ifndef _T
#define _T(x) x
#endif
#ifndef _tprintf_s
#define _tprintf_s printf_s
#define _stprintf_s sprintf_s
#define _tcscpy_s strcpy_s
#endif
#endif
typedef const Char* PCStr;
typedef Char* PStr;
#ifndef BUFSIZE
#define BUFSIZE 256
#endif
#ifndef max
#define max(a,b) ((a) < (b) ? (b) : (a))
#define min(a,b) ((a) < (b) ? (a) : (b))
#endif
#endif
template <typename classTag>
class CLMemPoolBlock;
template <typename classTag>
class CLMemPool;
内存池表类型
class MemPoolsTable
:public std::map< CLMemPool<void*>*, std::tstring>,
public CLLock
{
};
//取得内存池表
inline MemPoolsTable* getMemPoolsTable() {
static MemPoolsTable _mplst;
return &_mplst;
}
增加内存池到内存池表
inline void addMemPoolToTable(PCStr name, CLMemPool<void*>* pMemPool)
{
getMemPoolsTable()->lock();
(*getMemPoolsTable())[pMemPool] = (name == nullptr ? _T("") : name);
getMemPoolsTable()->unlock();
}
//内存池对象单元模板类
template <typename classTag>
class CLMemPoolUnit {
friend class CLMemPool<classTag>;
friend class CLMemPoolBlock<classTag>;
public:
struct DataHead {
CLMemPoolUnit<classTag>* pPre;
CLMemPoolUnit<classTag>* pNext;
CLMemPoolBlock<classTag>* pThisBlock;
bool bIsCreate;
bool bIsUsed;
};
private:
DataHead hdr;
classTag data;//包裹数据对象
//在构造时候显示调用
CLMemPoolUnit<classTag>* init(
CLMemPoolBlock<classTag>* _pThisBlock = 0,
CLMemPoolUnit<classTag>* _pPre = 0,
CLMemPoolUnit<classTag>* _pNext = 0,
bool _isCreate = false,
bool _isUsed = false
) {
hdr.pThisBlock = _pThisBlock;
hdr.pPre = _pPre;
hdr.pNext = _pNext;
hdr.bIsCreate = _isCreate;
hdr.bIsUsed = _isUsed;
return this;
}
//注意:构造和析构函数用于显示的调用来构造和析构内部包裹对象
//他们不应该被系统调用,且内部不能有任何的数据处理过程;
CLMemPoolUnit(){
}
template <typename... Args>
CLMemPoolUnit(Args&&... args):data(std::forward<Args>(args)...){
}
~CLMemPoolUnit() {
}
public:
inline CLMemPoolBlock<classTag>