这是一个任意对象的无限维数组模板,实现比较多功能,能做很多事情,泛型实例化的对象的显式动态构造或析构,有一个微型内存回收手法可以高效利用到多维运算,比如神经网络,举证计算中,共享下代码。
其中宏CLArrayObj是用于定义类类型数组的,CLArrayV是用于定义基础值类型数组的两个宏;
先来看看应用!
class B {//先定义的一个演示类B,备用
public:
double a = RAND_F_0_1();//生成0-1随机数
double b = RAND_F_0_1();
int* p;
class _A {
_A() { RAND_SET_SEED(); }
};
static _A seed;
B() {
p = new int[15];
}
B(const B& tag) {//注意处理赋值构造对动态指针影响
p = new int[15];
*this = tag;
}
B& operator=(const B& tag) {//注意处理赋值函数对动态指针影响
a = tag.a;
b = tag.b;
return *this;
}
~B() {
delete[] p;
}
B& operator=(VT v) { return a = b = v, *this; }
};
//用宏实例化模板类
CLArrayObj(B, ArrObj);//B是前面定义的类,实例化到名为ArrObj的多维数组类,下同
//CLArrayV(VT, ArrV);
CLArrayV(double, ArrB);//实例化double类型的数组类
CLArrayV(double, CDouble);
CLArrayV(int, CInt);
CLArrayV(long long, CLonglong);
void main() {
ArrObj obj1 ;
//定义任意维度数组,编号小于0按0计入,不用事先定义对象大小和维度,可以任意指定,下标会自动取整
obj1[-1][1][5][3][2][12][2.5][5][6][1][9][8][66][-25][66][5][0][77] = 3.1415926;
CDouble cd1;
CLonglong cd2 = (int)1;
CInt cd3 = 1.5;
cd1[1] = 3;
cd1[2] = 2;
cd1[3] = cd1[1] * cd2[2];
cd1++;
++cd1;
cd1--;
++cd1--;
int a11 = 1 + ++cd2-- + 2.5 - cd1 + 50;
cd1 = 1 + cd2 + 2.5 - cd1 + 50;
double ii2 = 0;
ii2 = cd1 + 2;
ii2 = cd1 - 2;
ii2 = cd1 * 2;
ii2 = cd1 / 2;
ii2 = cd1 % 2;
ii2 = 2 + cd1;
ii2 = 2 - cd1;
ii2 = 2 * cd1;
ii2 = 2 / cd1;
ii2 = 2 % (int)cd1;
CDouble* p = (CDouble*)malloc(sizeof(CDouble));
p->CDouble::CLArrayTemplateV();
*p = cd1;
p->CDouble::~CLArrayTemplateV();
free(p);
//return;
ArrB* a = (new ArrB);
//接受数组赋值
*a ={ 1, 1.1,222,222,222,222,222,222,222,222};
(*a).clear();
ArrB b = { 3 };
*a = b;
*a = { 4,44,444,555,666,777,888,999};
*a = 1;
*a = 1.1;
delete a;
//return;
RAND_SEED();
int ii,aa,jj,bb;
//无限维测试
for (size_t kkk = 0; kkk < 10; kkk++)
{
ArrObj t1;
t1[1] = 1;
t1.clear();
CLTick tk;
for (int i = 0; i < 9; ++i)
{
int a = RAND_I_Ai_B(0, 100);
aa = a;
ii = i;
auto v = &t1;
for (int j = 0; j < a; ++j)
{
jj = j;
int b = RAND_I_Ai_B(10, 200);
bb = b;
v = (ArrV*) & (v->at(b));
}
*v = (VT)RAND_F_A_B(-99, 0);
}
t1.clear();
for (int i = 0; i < 9000; ++i)
{
int a = RAND_I_Ai_B(0, 100);
aa = a;
ii = i;
auto v = &t1;
for (int j = 0; j < a; ++j)
{
jj = j;
int b = RAND_I_Ai_B(5, 105);
bb = b;
v = (ArrV*) & (v->at(b));
}
*v = RAND_F_A_B(1, 5);
}
printf("\n\n清理后,耗时 %.5f s , mem a= %lld b ,u= %lld b ,s= %lld b , \n\n", tk.getSpendTime(0), t1.getMemerySize(), t1.getUsedMemerySize(), t1.getSpareMemerySize());
t1.clear();
printf("\n\n清理后,耗时 %.5f s , mem a= %lld b ,u= %lld b ,s= %lld b , \n\n", tk.getSpendTime(1), t1.getMemerySize(), t1.getUsedMemerySize(), t1.getSpareMemerySize());
t1.releaseMemery();
}
return;
}
以下是代码实现
CLArrayTemplate.h
#pragma once
#ifndef __CL_ARRAYTEMPLATE_H__
#define __CL_ARRAYTEMPLATE_H__
#include "windows.h"
#include
#include
#ifndef __CL_VALUEPACK__
#define __CL_VALUEPACK__
//基础数值类型的对象化封装类模板
template<class T>class CLValuePacking {
public:
using obj = CLValuePacking<T>;
using pObj = CLValuePacking<T>*;
using pObjc = const CLValuePacking<T>*;
using ref = CLValuePacking<T> &;
using refc = const CLValuePacking<T> &;
T v;
//不对值对象做初始化
inline CLValuePacking() {
#ifdef _DEBUG
v = 0;
#endif
}
inline CLValuePacking(T _v) {
v = _v;
}
inline CLValuePacking(refc tag) {
v = tag;
}
inline ~CLValuePacking() {
#ifdef _DEBUG
memset(&v, 0xFF, sizeof(T));
#endif
}
inline size_t memSize() { return sizeof(T); }
inline operator T() const { return v; }
inline operator T& () { return v; }
inline T& operator=(const T& _v) { return v = _v, v; }
template<class otherT>inline T& operator=(const otherT& _v) { return v = _v, v; }
//运算
inline T& operator--() {
return --v, v;
}
inline T& operator++() {
return ++v, v;
}
inline obj operator--(int) {
obj a = *this;
--v;
return a;
}
inline obj operator++(int) {
obj a = *this;
++v;
return a;
}
template<class otherT>
inline T& operator+=(const otherT& _v) {
return v += _v, v;
}
template<class otherT>
inline T& operator-=(const otherT& _v) {
return v -= _v, v;
}
template<class otherT>
inline T& operator*=(const otherT& _v) {
return v *= _v, v;
}
template<class otherT>
inline T& operator/=(const otherT& _v) {
return v /= _v, v;
}
template<class otherT>
inline T operator+(const otherT& _v) {
return v + _v;
}
template<class otherT>
inline T operator-(const otherT& _v) {
return v - _v;
}
template<class otherT>
inline T operator*(const otherT& _v) {
return v * _v;
}
template<class otherT>
inline T operator/(const otherT& _v) {
return v / _v;
}
template<class otherT>
inline bool operator==(const otherT& _v) {
return v == _v;
}
inline int operator%(int _v) {
return (((int)(v)) % _v);
}
};
template<class T, class otherT, class Ret>
Ret operator+(const otherT& v, const CLValuePacking<T>& t) {
return v + T(t);
}
template<class T, class otherT, class Ret>
Ret operator-(const otherT& v, const CLValuePacking<T>& t) {
return v - T(t);
}
template<class T, class otherT, class Ret>
Ret operator*(const otherT& v, const CLValuePacking<T>& t) {
return v * T(t);
}
template<class T, class otherT, class Ret>
Ret operator/(const otherT& v, const CLValuePacking<T>& t) {
return v / T(t);
}
//实例化 基础数值型包装类 模版类
#define CLVPack(valueClass,definedClassName)\
template class CLValuePacking;\
typedef CLValuePacking definedClassName;\
typedef definedClassName& definedClassName##R;\
typedef const definedClassName& definedClassName##RC;\
typedef definedClassName* P##definedClassName;\
typedef const definedClassName* PC##definedClassName;
#endif
//对象类型 多维安全数组类 模版类(注意:对象类应该妥善处理对象赋值或拷贝构造对内部动态指针变量的影响,避免引起多重释放)
template <class T>
class CLArrayTemplate {
public:
using obj = CLArrayTemplate<T>;
using pObj = CLArrayTemplate<T>*;
using pObjc = const CLArrayTemplate<T>*;
using ref = CLArrayTemplate<T> &;
using refc = const CLArrayTemplate<T> &;
using vlist = std::initializer_list<T>;
using data = std::vector<CLArrayTemplate<T>*>;
using pdata = std::vector<CLArrayTemplate<T>*>*;
protected:
class VPackage {//包装类
public:
T* m_value; //节点值对象
inline VPackage()
:m_value(new T)
{
}
inline ~VPackage() {
if (m_value != 0) {
delete m_value;
m_value = 0;
}
}
};
VPackage m_vPack;
pdata m_sublst;//节点的子对象表
bool m_createByLst;
std::stack<pObj> objLibrary;//mem pool
void _release() {
//释放内存池
_releaseLib();
//释放表本身,及子连
if (m_sublst != NULL) {
for (size_t i = 0, si = m_sublst->size(); i < si; i++) {
auto pc = m_sublst->at(i);
if (pc != 0) {
_deleteOne(pc);
}
}
delete m_sublst;
m_sublst = NULL;
}
};
void _releaseLib() {
while (!objLibrary.empty()) //释放库
{
pObj pc = objLibrary.top();
objLibrary.pop();
_deleteOne(pc);
}
};
virtual pObj _newObj() {
pObj pnew;
if (!objLibrary.empty()) {
pnew = objLibrary.top();
objLibrary.pop();
pnew->m_vPack.VPackage::VPackage();
pnew->m_createByLst = false;
return pnew;
}
else {
pnew = (pObj)malloc(sizeof(obj));
pnew->CLArrayTemplate::CLArrayTemplate();
return pnew;
}
}
virtual void _storeOne(void* p) {
((pObj)p)->clear();//清理子连
((pObj)p)->m_vPack.VPackage::~VPackage();//析构对象
objLibrary.push((pObj)p);
}
virtual void _deleteOne(void* p) {
((pObj)p)->CLArrayTemplate::~CLArrayTemplate();
free(p);
}
inline size_t _getObjSizeof() const {
return _getClassSizeof() + (m_vPack.m_value ? sizeof(T) : 0);
}
inline virtual size_t _getClassSizeof() const {
return sizeof(obj);
}
inline void* _newData() { return new data; }
void _copyList(const pdata& tag_sublst) {
size_t lsi = (tag_sublst != 0 ? tag_sublst->size() : 0);
if (lsi > 0) {
if (!m_sublst)
m_sublst = (pdata)_newData();
size_t si = m_sublst->size();
if (si < lsi) {
m_sublst->resize(lsi, (pObj)0);
}
for (size_t i = 0; i < lsi; i++)
{
auto& p = m_sublst->at(i);
auto& pt = tag_sublst->at(i);
if (pt != 0) {
if (p == 0)
p = _newObj();
*p->m_vPack.m_value = *pt->m_vPack.m_value;
}
}
}
}
void _clear() {
if (m_sublst != NULL) {
for (size_t i = 0, si = m_sublst->size(); i < si; i++) {
auto& pc = m_sublst->at(i);
if (pc != 0) {
_storeOne(pc);
}
}
m_sublst->clear();
}
};
public:
//取得对象内存总占用大小,包括已使用的内存和已缓存在内存池中备用的内存
size_t getMemerySize() const {
size_t sii = getUsedMemerySize();
sii += getSpareMemerySize();
return sii;
}
//释放结构所有占用内存,包括已使用的内存和已缓存在内存池中备用的内存
void releaseMemery() {
_release();
}
//取得已在内存池中保留的备用内存的占用大小(不包含正在使用的内存)
size_t getSpareMemerySize() const {
size_t sii = 0;
std::stack<pObj> stk2 = objLibrary;
while (!stk2.empty())
{
sii += (stk2.top()->getMemerySize());
stk2.pop();
}
return sii;
}
//释放已在内存池中保留的备用内存的占用大小(不包含正在使用的内存)
void releaseSpareMemery() {
_releaseLib();
}
//取得对象已使用的内存占用大小(不包缓存在内存池中备用的内存)
size_t getUsedMemerySize()const {
size_t sii = _getObjSizeof();
if (m_sublst != NULL) {
sii += (m_sublst->capacity() * sizeof(pObj));
for (size_t i = 0, si = m_sublst->size(); i < si; ++i)
{
pObj p = (m_sublst->at(i));
if (p)
sii += p->getMemerySize();
}
}
return sii;
}
inline CLArrayTemplate()
:m_sublst(0), m_createByLst(false) {
}
template<class otherT>
inline CLArrayTemplate(otherT v)
: m_sublst(0), m_createByLst(false) {
*m_vPack.m_value = v;
}
inline CLArrayTemplate(refc tag)
: m_sublst(0), m_createByLst(false) {
*this = tag;
}
inline CLArrayTemplate(const vlist& _Ilist)
: m_sublst(0), m_createByLst(true) {
*this = _Ilist;
}
//析构函数 释放所有对象及子节点的内存
inline virtual ~CLArrayTemplate() {
_release();
}
inline ref operator =(T v) {
return (m_createByLst = false, *m_vPack.m_value = v), * this;
}
ref operator =(refc tag) {
if (!tag.m_createByLst)
m_createByLst = false, * m_vPack.m_value = (*tag.m_vPack.m_value);
_copyList(tag.m_sublst);
return *this;
}
ref operator =(const vlist& _Ilist) {
size_t lsi = _Ilist.size();
if (lsi > 0) {
if (!m_sublst)
m_sublst = (pdata)_newData();
auto si = m_sublst->size();
if (si < lsi) {
m_sublst->resize(lsi, (pObj)0);
}
for (size_t i = 0; i < lsi; i++)
{
auto& p = m_sublst->at(i);
if (p == 0)
p = _newObj();
*p->m_vPack.m_value = *(_Ilist.begin() + i);
}
}
return *this;
}
//向队列中直接产生i个实例对象,以便后续at或[]操作使用,在未具体调用单元之前,
//函数就会将对象准备就绪(动态申请内存),函数不会改变已有的对象;
void generate(int i) {
size_t _i = (i < 0 ? 0 : i);
if (!m_sublst)m_sublst = new data;
if (m_sublst->size() >= _i) {
for (size_t i = 0; i < _i; i++)
{
auto& pc = m_sublst->at(i);
if (pc == 0)
pc = _newObj();
}
return;
}
m_sublst->resize(_i, (pObj)0);
for (size_t i = 0; i < _i; i++)
{
auto& pc = m_sublst->at(i);
if (pc == 0)
pc = _newObj();
}
return;
}
//就会删除多余的链表对象,保留指定的个数,不会初始化已有的对象
void resize(int i) {
size_t _i = (i < 0 ? 0 : i);
if (!m_sublst)
m_sublst = new data;
size_t si = m_sublst->size();
if (si > _i) {
for (size_t i = si; i > _i; --i)
{
auto& pc = m_sublst->at(i - 1);
if (pc != 0) {
_storeOne(pc);
pc = 0;
}
}
m_sublst->resize(_i);
return;
}
else if (si < _i)
m_sublst->resize(_i, 0);
return;
}
//返回内部值的引用
inline T& operator()() { return *m_vPack.m_value; }
//清除子连,保留子连对象,区别于reset();
inline void clear() {
_clear();
}
//可以使得对象本身就像一个计算数一样被使用于数学运算,常值类型转换
inline operator T() const {
return *m_vPack.m_value;
}
//可以使得对象本身就像一个计算数一样被使用于数学运算,可变类型转换
inline operator T& () {
return *m_vPack.m_value;
}
//取得链的第i个对象,i<0自动取0,i>链最大数时自动扩容,因此i永远不会产生越界错误
ref at(size_t _i) {
if (!m_sublst)
m_sublst = new data;
if (m_sublst->size() < _i + 1) {
m_sublst->resize(_i + 1, (pObj)0);
auto& pc = m_sublst->at(_i);
pc = _newObj();
return *pc;
}
auto& pc = m_sublst->at(_i);
if (pc == 0)
pc = _newObj();
return *pc;
}
template<class Ti>
inline ref at(const Ti& i) {
return at(i < 0 ? 0 : size_t(i));
}
//取得链的第i个对象,i<0自动取0,i>链最大数时自动扩容,因此i永远不会产生越界错误
inline ref operator[](size_t i) { return at(i); }
template<class Ti>
inline ref operator[](const Ti& i) { return at(i); }
//取得链的单元数
inline size_t size() const {
return m_sublst != NULL ? m_sublst->size() : 0;
}
//向连的末尾增加元素
inline ref push_back(T v) {
return at(size()) = v, *this;
}
};
//实例化 对象类型的 多维安全数组 模版类(注意:对象类应该妥善处理对象赋值或拷贝构造对内部动态指针变量的影响,避免引起多重释放)
#define CLArrayObj(objClass,definedClassName)\
template class CLArrayTemplate;\
typedef CLArrayTemplate definedClassName;\
typedef definedClassName& definedClassName##R;\
typedef const definedClassName& definedClassName##RC;\
typedef definedClassName* P##definedClassName;\
typedef const definedClassName* PC##definedClassName;
//基础数值类型 多维安全数组类 模版类
template<class T>
class CLArrayTemplateV :public CLArrayTemplate<CLValuePacking<T>> {
public:
using obj = CLArrayTemplateV<T>;
using obj_base = CLArrayTemplate<CLValuePacking<T>>;
using pObj = CLArrayTemplateV<T>*;
using pObj_base = CLArrayTemplate<CLValuePacking<T>>*;
using ref_base = CLArrayTemplate<CLValuePacking<T>> &;
using refc_base = const CLArrayTemplate<CLValuePacking<T>> &;
using ref = CLArrayTemplateV<T> &;
using refc = const CLArrayTemplateV<T> &;
using vlist = std::initializer_list<CLValuePacking<T>>;
protected:
virtual pObj _newObj() {
pObj pnew;
if (!obj_base::objLibrary.empty()) {
pnew = (pObj)obj_base::objLibrary.top();
obj_base::objLibrary.pop();
pnew->clear();//清理子连
pnew->reset();//重置对象
return pnew;
}
else {
pnew = (pObj)malloc(sizeof(obj));
pnew->CLArrayTemplateV::CLArrayTemplateV();
return pnew;
}
}
virtual void _storeOne(void* p) {
obj_base::objLibrary.push((pObj)p);
}
virtual void _deleteOne(void* p) {
((pObj)p)->CLArrayTemplateV::~CLArrayTemplateV();
free(p);
}
inline virtual size_t _getClassSizeof() const {
return sizeof(obj);
}
public:
inline void reset() {
obj_base::m_createByLst = false;
(*obj_base::m_vPack.m_value) = 0;
}
//构造函数 并初始化值为
inline CLArrayTemplateV()
{
(*obj_base::m_vPack.m_value).v = 0;
}
template<class otherT>
inline CLArrayTemplateV(otherT v)
{
(*obj_base::m_vPack.m_value).v = v;
}
CLArrayTemplateV(refc tag)
{
if (tag.m_createByLst)
obj_base::m_createByLst = true, (*obj_base::m_vPack.m_value).v = 0;
else
(*obj_base::m_vPack.m_value).v = (*tag.m_vPack.m_value).v;
obj_base::_copyList(tag.m_sublst);
}
CLArrayTemplateV(const vlist& _Ilist)
{
obj_base::operator = (_Ilist);
obj_base::m_createByLst = true;
(*obj_base::m_vPack.m_value).v = 0;
}
inline virtual ~CLArrayTemplateV() {
obj_base::_release();
}
template<class otherT>
inline ref operator =(otherT value) {
return (obj_base::m_createByLst = false, (*obj_base::m_vPack.m_value).v = T(value)), * this;
}
//inline ref operator =(T value) {return (obj_base::m_createByLst = false, (*obj_base::m_vPack.m_value).v = value), * this;}
ref operator =(refc tag) {
if (tag.m_createByLst)
obj_base::m_createByLst = true, (*obj_base::m_vPack.m_value).v = 0;
else
(*obj_base::m_vPack.m_value).v = (*tag.m_vPack.m_value).v;
obj_base::_copyList(tag.m_sublst);
return *this;
}
inline ref operator =(const vlist& _Ilist) {
return obj_base::operator = (_Ilist), * this;
}
//可以使得对象本身就像一个计算数一样被使用于数学运算,常值类型转换
inline operator T() const {
return (*obj_base::m_vPack.m_value).v;
}
//可以使得对象本身就像一个计算数一样被使用于数学运算,可变类型转换
inline operator T& () {
return (*obj_base::m_vPack.m_value).v;
}
inline ref at(size_t i) {
return (ref) * &(obj_base::at(i));
}
template<class Ti>
inline ref at(const Ti& i) {
return (ref) * &(obj_base::at(i < 0 ? 0 : size_t(i)));
}
//取得链的第i个对象,i<0自动取0,i>链最大数时自动扩容,因此i永远不会产生越界错误
inline ref operator[](size_t i) { return (ref) * &(obj_base::at(i)); }
template<class Ti>
inline ref operator[](const Ti& i) { return (ref) * &(obj_base::at(i < 0 ? 0 : size_t(i))); }
//运算
obj operator--(int) {
obj a = *this;
++((*obj_base::m_vPack.m_value).v);
return a;
}
obj operator++(int) {
obj a = *this;
++((*obj_base::m_vPack.m_value).v);
return a;
}
inline ref operator--() {
return --(*obj_base::m_vPack.m_value).v, * this;
}
inline ref operator++() {
return ++(*obj_base::m_vPack.m_value).v, * this;
}
inline int operator%(int v) {
return (((int)((*obj_base::m_vPack.m_value).v)) % v);
}
};
//实例化 基础数值类型的 多维安全数组 模版类
#define CLArrayV(baseValueClass,definedClassName)\
template class CLArrayTemplateV;\
typedef CLArrayTemplateV definedClassName;\
typedef definedClassName& definedClassName##R;\
typedef const definedClassName& definedClassName##RC;\
typedef definedClassName* P##definedClassName;\
typedef const definedClassName* PC##definedClassName;
#endif