* 作为数组类模板,肯定没有vector做得好,可是普通的数组有1个优点就是能直接操作内存。vector在这方面就不是非常方便了。

网上尽管也有数组类模板。多维的设计基本上都不是非常好。我这个类模板多维的设计借鉴了vector,如2维数组vector<vector<int>> vvArr;下附源代码*/

#pragma once

enum E_POSIITION
{
begin_position = 0,
end_position
}; // CBaseArray作为一个最原始基类,不同意构造对象
template <class T>
class CBaseArray
{
protected:
CBaseArray():m_pTMemory(NULL),m_uMemSize(0)
{ } virtual ~CBaseArray()
{ } public:
// member method
const T* GetMemory(UINT _uIdx = 0) const
{
ASSERT(_uIdx < m_uMemSize); return m_pTMemory+_uIdx;
}
T* GetMemory(UINT _uIdx = 0)
{
ASSERT(_uIdx < m_uMemSize); return m_pTMemory+_uIdx;
} const UINT GetSize() const
{
return m_uMemSize;
}
UINT GetSize()
{
return m_uMemSize;
} void MemCopy(UINT _uPos, const T* _pBuff, UINT _uSize)
{
ASSERT(NULL != _pBuff);
ASSERT(_uSize+_uPos <= m_uMemSize);
memcpy(GetMemory(_uPos), _pBuff, _uSize*sizeof(T));
} void ResetValue(const T tValue)
{
for (UINT uIdx = 0; uIdx < m_uMemSize; uIdx++)
{
MemCopy(uIdx, &tValue, 1);
}
} void ResetRandMemory()
{
srand(GetTickCount());
for (UINT uIdx = 0; uIdx < m_uMemSize*sizeof(T); uIdx++)
{
*(PBYTE(m_pTMemory) + uIdx) = rand();
}
} protected:
BOOL MallocMem(UINT _uSize)
{
// 先申请内存保存原有的数据
T *tTemp = new T[m_uMemSize];
ASSERT(NULL != tTemp); memcpy(tTemp, m_pTMemory, m_uMemSize*sizeof(T)); // 释放原有内存
delete[] m_pTMemory;
m_pTMemory = NULL; // 又一次分配内存,并保存足够的原有的数据
m_pTMemory = new T[_uSize];
ASSERT(NULL != m_pTMemory);
if (NULL == m_pTMemory)
{
return FALSE;
} UINT uMinSize = min(_uSize, m_uMemSize);
memcpy(m_pTMemory, tTemp, uMinSize*sizeof(T));
ZeroMemory(m_pTMemory, uMinSize*sizeof(T)); m_uMemSize = _uSize;
delete[] tTemp;
tTemp = NULL; return TRUE;
} T *m_pTMemory;
UINT m_uMemSize;
}; // 1维数组模板类
template <class T>
class CMyArray : public CBaseArray<T>
{
public:
CMyArray()
{ } CMyArray(UINT _uSize, const T& _tValue)
{
SetSize(_uSize);
ResetValue(_tValue);
} CMyArray(const CMyArray& _other)
{
if (m_uMemSize > 0)
{
delete[] m_pTMemory;
m_pTMemory = NULL;
} m_pTMemory = new T[_other.m_uMemSize];
ASSERT(NULL != m_pTMemory); m_uMemSize = _other.m_uMemSize;
memcpy(m_pTMemory, _other.m_pTMemory, _other.m_uMemSize*sizeof(T));
} ~CMyArray()
{
if ((m_uMemSize > 0) && (NULL != m_pTMemory))
{
delete[] m_pTMemory;
m_pTMemory = NULL;
}
} // member method
BOOL SetSize(UINT _uSize)
{
return MallocMem(_uSize);
}
BOOL SetSize(UINT _uSize, const T& _tValue)
{
if (!SetSize(_uSize))
{
return FALSE;
} ResetValue(_tValue); return TRUE;
} void ReleaseArray()
{
if (m_uMemSize > 0)
{
delete[] m_pTMemory;
m_pTMemory = NULL;
m_uMemSize = 0;
}
} // 重载两种类型的[]操作符
const T& operator[](UINT _uIdx) const
{
ASSERT(_uIdx < m_uMemSize); return m_pTMemory[_uIdx];
}
T& operator[](UINT _uIdx)
{
ASSERT(_uIdx < m_uMemSize); return m_pTMemory[_uIdx];
} CMyArray& operator=(const CMyArray& _other)
{
ReleaseArray(); m_pTMemory = new T[_other.m_uMemSize];
ASSERT(NULL != m_pTMemory); m_uMemSize = _other.m_uMemSize;
memcpy(m_pTMemory, _other.m_pTMemory, _other.m_uMemSize*sizeof(T)); return *this;
} BOOL operator==(const CMyArray& _other)
{
if (m_uMemSize == _other.GetSize())
{
if (0 == memcmp(GetMemory(0), _other.GetMemory(0), m_uMemSize*sizeof(T)))
{
return TRUE;
}
} return FALSE;
} void Insert(E_POSIITION _ePostion, const CMyArray& _other)
{
// 建立暂时变量先保存当前对象
CMyArray myTemp(*this); // 释放当前对象的内容
ReleaseArray(); // 为当前对象申请新的内存以存放合并后的内容
SetSize(myTemp.GetSize() + _other.GetSize()); if (begin_position == _ePostion)
{
MemCopy(0, _other.GetMemory(0), _other.GetSize());
MemCopy(_other.GetSize(), myTemp.GetMemory(0), myTemp.GetSize());
}
else if (end_position == _ePostion)
{
MemCopy(0, myTemp.GetMemory(0), myTemp.GetSize());
MemCopy(myTemp.GetSize(), _other.GetMemory(0), _other.GetSize());
}
} protected:
private:
}; // 2维数组模板类
template<class T>
class CMy2DArray
{
public:
CMy2DArray()
{ } CMy2DArray(UINT _uX, UINT _uY)
{
SetSize(_uX, _uY);
} CMy2DArray(UINT _uX, UINT _uY, const T& _tValue)
{
SetSize(_uX, _uY);
ResetValue(_tValue);
} CMy2DArray(const CMy2DArray& _other)
{
SetSize(_other.m_uX, _other.m_uY);
for (UINT uRow = 0; uRow < _other.m_uX; uRow++)
{
m_tArray[uRow] = _other.m_tArray[uRow];
}
} ~CMy2DArray()
{ } // member method
// 设置二维数组的大小
BOOL SetSize(UINT _uX, UINT _uY)
{
m_uX = _uX;
m_uY = _uY; if (!m_tArray.SetSize(_uX))
{
return FALSE;
} for (UINT uIdx = 0; uIdx < _uX; uIdx++)
{
if (!m_tArray[uIdx].SetSize(_uY))
{
return FALSE;
}
} return TRUE;
} void ResetValue(const T tValue)
{
for (UINT uRow = 0; uRow < m_uX; uRow++)
{
m_tArray[uRow].ResetValue(tValue);
}
} void ResetRandMemory()
{
for (UINT uRow = 0; uRow < m_uX; uRow++)
{
m_tArray[uRow].ResetRandMemory();
}
} UINT GetXSize()
{
return m_uX;
} UINT GetYSize()
{
return m_uY;
} T* GetMemory(UINT _uX, UINT _uY)
{
ASSERT(_uX < m_uX);
ASSERT(_uY < m_uY); return m_tArray[_uX].GetMemory(_uY);
} const T& GetValue(UINT _uX, UINT _uY)
{
ASSERT(_uX < m_uX);
ASSERT(_uY < m_uY); return m_tArray[_uX][_uY];
} // 重载两个[]运算符,前一个为常量对象使用,后一个为非常量对象使用
const CMyArray<T>& operator[](UINT _uIdx) const
{
ASSERT(_uIdx < m_uX); return m_tArray[_uIdx];
}
CMyArray<T>& operator[](UINT _uIdx)
{
ASSERT(_uIdx < m_uX); return m_tArray[_uIdx];
} // 重载强制类型转换符
operator CMyArray<CMyArray<T>>&()
{
return m_tArray;
} // 重载()操作符
CMyArray<CMyArray<T>>& operator ()()
{
return m_tArray;
} // 重载=运算符
CMy2DArray& operator=(const CMy2DArray& _other)
{
ReleaseArray(); SetSize(_other.m_uX, _other.m_uY);
for (UINT uRow = 0; uRow < _other.m_uX; uRow++)
{
m_tArray[uRow] = _other.m_tArray[uRow];
} return *this;
} protected:
void ReleaseArray()
{
m_tArray.ReleaseArray();
} private:
UINT m_uX;
UINT m_uY;
CMyArray<CMyArray<T>> m_tArray;
}; // 3维数组模板类
template<class T>
class CMy3DArray
{
public:
CMy3DArray() : m_uX(0), m_uY(0), m_uZ(0)
{ } CMy3DArray(UINT _uX, UINT _uY, UINT _uZ)
{
SetSize(_uX, _uY, _uZ);
} CMy3DArray(UINT _uX, UINT _uY, UINT _uZ, const T& _tValue)
{
SetSize(_uX, _uY, _uZ);
ResetValue(_tValue);
} CMy3DArray(const CMy3DArray& _other)
{
SetSize(_other.m_uX, _other.m_uY, _other.m_uZ);
for (UINT uRow = 0; uRow < _other.m_uX; uRow++)
{
m_t3DArr[uRow] = _other.m_t3DArr[uRow];
}
} ~CMy3DArray()
{ } // member method
BOOL SetSize(UINT _uX, UINT _uY, UINT _uZ)
{
m_uX = _uX;
m_uY = _uY;
m_uZ = _uZ; if (!m_t3DArr.SetSize(_uX))
{
return FALSE;
}
for (UINT uIdx = 0; uIdx < _uX; uIdx++)
{
if (!m_t3DArr[uIdx].SetSize(_uY, _uZ))
{
return FALSE;
}
} return TRUE;
} void ResetValue(const T tValue)
{
for (UINT uRow = 0; uRow < m_uX; uRow++)
{
m_t3DArr[uRow].ResetValue(tValue);
}
} void ResetRandMemory()
{
for (UINT uRow = 0; uRow < m_uX; uRow++)
{
m_t3DArr[uRow].ResetRandMemory();
}
} T* GetMemory(UINT _uX, UINT _uY, UINT _uZ)
{
ASSERT(_uX < m_uX);
ASSERT(_uY < m_uY);
ASSERT(_uZ < m_uZ); return m_t3DArr[_uX].GetMemory(_uY, _uZ);
} // 重载两个[]运算符,前一个为常量对象使用,后一个为非常量对象使用
const CMy2DArray<T>& operator[](UINT _uIdx) const
{
ASSERT(_uIdx < m_uX); return m_t3DArr[_uIdx];
}
CMy2DArray<T>& operator[](UINT _uIdx)
{
ASSERT(_uIdx < m_uX); return m_t3DArr[_uIdx];
} // 重载=运算符
CMy2DArray<T>& operator=(const CMy3DArray<T>& _other)
{
ReleaseArray(); SetSize(_other.m_uX, _other.m_uY, _other.m_uZ);
for (UINT uRow = 0; uRow < _other.m_uX; uRow++)
{
m_t3DArr[uRow] = _other.m_t3DArr[uRow];
} return *this;
} void ReleaseArray()
{
for (UINT uIdx = 0; uIdx < m_uX; uIdx++)
{
m_t3DArr[uIdx].ReleaseArray();
}
} UINT GetXSize()
{
return m_uX;
} UINT GetYSize()
{
return m_uY;
} UINT GetZSize()
{
return m_uZ;
} private:
UINT m_uX;
UINT m_uY;
UINT m_uZ;
CMyArray<CMy2DArray<T>> m_t3DArr;
};

C++数组类模板的更多相关文章

  1. 网易云课堂_C++程序设计入门(下)_第10单元:月映千江未减明 – 模板_第10单元 - 单元作业:OJ编程 - 创建数组类模板

    第10单元 - 单元作业:OJ编程 - 创建数组类模板 查看帮助 返回   温馨提示: 1.本次作业属于Online Judge题目,提交后由系统即时判分. 2.学生可以在作业截止时间之前不限次数提 ...

  2. C++走向远洋——64(项目三、数组类模板)

    */ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:text.cpp * 作者:常轩 * 微信公众号:Worldhe ...

  3. C++解析(27):数组、智能指针与单例类模板

    0.目录 1.数组类模板 1.1 类模板高效率求和 1.2 数组类模板 1.3 堆数组类模板 2.智能指针类模板 2.1 使用智能指针 2.2 智能指针类模板 3.单例类模板 3.1 实现单例模式 3 ...

  4. C++——模板、数组类

    1.函数模板:可以用来创建一个通用功能的函数,以支持多种不同形参,进一步简化重载函数的函数体设计. 声明方法:template<typename 标识符> 函数声明 求绝对值的模板 #in ...

  5. C++中的数据类模板

    1,预备知识: 1,模板参数可以是数值型参数(非类型参数): 1,代码示例: template <typename T, int N> void func() { T a[N]; // 使 ...

  6. 类模板、Stack的类模板实现(自定义链栈方式,自定义数组方式)

    一.类模板 类模板:将类定义中的数据类型参数化 类模板实际上是函数模板的推广,可以用相同的类模板来组建任意类型的对象集合 (一).类模板的定义 template  <类型形参表> clas ...

  7. YTU 2642: 填空题:类模板---求数组的最大值

    2642: 填空题:类模板---求数组的最大值 时间限制: 1 Sec  内存限制: 128 MB 提交: 646  解决: 446 题目描述   类模板---求数组的最大值    找出一个数组中的元 ...

  8. C++基础 (9) 第九天 编译器对模板类的二次编译 类模板 自定义数组类

    1 昨日回顾 2 编译器对于模板的二次编译 写一个模板函数 然后进行调用 g++ template.cpp -o template // 汇编 g++ -S template.cpp –o templ ...

  9. 使用类模板的C++线性表实现(数组方式)

    main.h #ifndef _MAIN_H_ #define _MAIN_H_ #include <iostream> #include <exception> #inclu ...

随机推荐

  1. CSS中的五大字体家族(cursive 手写字体族更吸引我)

    这是CSS中的五大字体家族. serifserif 中文翻译为“衬线字体族”.serif 具有末端加粗.扩张或尖细末端,或以实际的衬线结尾的一类字体.可以看出 serif 总是在文字末端做文章,这样做 ...

  2. SQLServer2008 关于CASE WHEN

    CASE WHEN的两种格式 1.简单Case函数 CASE sex WHEN '1' THEN '男' WHEN '2' THEN '女' ELSE '其他' END 2.Case搜索函数 CASE ...

  3. Android Activity has leaked window that was originally added

    今天调试程序时log中突然打印这样的错误,但是程序并没有crash,为了不放过一个错误,我决定调查一下. 当时是离开一个activity,然后提示是否退出此界面,接下来就打印此错误: - ::): A ...

  4. “发布后tomcat中的classes目录为空”问题

    办法:Project-clean,ok,问题解决.

  5. php基础知识 书写格式

    PHP,是英文超文本预处理语言Hypertext Preprocessor的递归缩写.PHP 是一种 HTML 内嵌式的语言,是一种在服务器端执行的嵌入HTML文档的脚本语言. php嵌入页面的标记有 ...

  6. JavaScript函数和window对象

    一.什么是函数 函数的含义:类似于Java中的方法,是完成特定任务的代码语句块 使用更简单:不用定义属于某个类,直接使用 二.常用系统函数 parseInt ("字符串")     ...

  7. 蛮好用的局域网测试工具iperf

    公司局域网总是莫名其妙的和一台机器网速很慢,虽然无法解决也无人解决,但是能有个有效的测试至少也会心里有数. 咱干不了网络硬件布线的活,就测测网速吧. 网上找了下,开始有文章介绍NetIQ Chario ...

  8. C# 写入二进制文件

    写入整型25 文件在MiniHex中显示 写入字符串I am happy 0A 6D - 6D - 这一行数据是C#把字符串转换为16进制形式 不知道为啥用MiniHex打开多了个0A 写入空&quo ...

  9. phpstorm 使用

    常用快捷 ctrl + / 单行注释 Alt+1 隐藏左侧任务栏 设置 1:control+shift+A功能可以搜索对应功能,把mouse:Change font size(Zoom) ...的按钮 ...

  10. " \t\r\n\f"是什么意思

    空格字符 \t 制表符 \r 回车符 \n 换行符 \f 换页符