#ifndef ARRAY_HEAD_FILE
#define ARRAY_HEAD_FILE
#pragma once
#include <afx.h>
//數組模板類
template<class TYPE,class ARG_TYPE=const TYPE&>
class CWHArray
{
//變量定義
protected:
TYPE * m_pData; //數組指針
int m_nMaxCount; //緩衝數目
int m_nElementCount; //元素數目
//函數定義
public:
//構造函數
CWHArray();
//析構函數
virtual ~CWHArray();
//信息函數
public:
//是否爲空
bool IsEmpty() const;
//獲取數目
int GetCount() const;
//功能數組
public:
//獲取緩衝
TYPE * GetData();
//獲取緩衝
const TYPE * GetData() const;
//增加元素
int Add(ARG_TYPE newElement);
//拷貝數組
void Copy(const CWHArray & Src);
//追加數組
int Append(const CWHArray & Src);
//獲取元素
TYPE & GetAt(int nIndex);
//獲取元素
const TYPE & GetAt(int nIndex) const;
//獲取元素
TYPE & ElementAt(int nIndex);
//獲取元素
const TYPE & ElementAt(int nIndex) const;
//操作函數
public:
//設置大小
void SetSize(int nNewSize);
//設置元素
void SetAt(int nIndex, ARG_TYPE newElement);
//設置元素
void SetAtGrow(int nIndex, ARG_TYPE newElement);
//插入數據
void InsertAt(INT_PTR nIndex, const CWHArray & Src);
//插入數據
void InsertAt(int nIndex, ARG_TYPE newElement, int nCount = 1);
//刪除數據
void RemoveAt(int nIndex, int nCount = 1);
//刪除元素
void RemoveAll();
//操作重載
public:
//操作重載
TYPE & operator[](int nIndex);
//操作重載
const TYPE & operator[](int nIndex) const;
//內存函數
public:
//釋放內存
void FreeMemory();
//申請內存
void AllocMemory(int nNewCount);
};
//構造函數
template<class TYPE, class ARG_TYPE>
CWHArray<TYPE, ARG_TYPE>::CWHArray()
{
m_pData = NULL;
m_nMaxCount = 0;
m_nElementCount = 0;
}
//析構函數
template<class TYPE, class ARG_TYPE>
CWHArray<TYPE,ARG_TYPE>::~CWHArray()
{
if (m_pData != NULL)
{
for (int i = 0; i<m_nElementCount; i++)
(m_pData + i)->~TYPE();
delete[](char *)m_pData;
m_pData = NULL;
}
}
//是否爲空
template<class TYPE, class ARG_TYPE>
inline bool CWHArray<TYPE, ARG_TYPE>::IsEmpty() const
{
return (m_pData == NULL);
}
//獲取數目
template<class TYPE, class ARG_TYPE>
inline int CWHArray<TYPE, ARG_TYPE>::GetCount() const
{
return m_nElementCount;
}
//獲取緩衝
template<class TYPE, class ARG_TYPE>
inline TYPE* CWHArray<TYPE, ARG_TYPE>::GetData()
{
return m_pData;
}
//獲取緩衝
template<class TYPE, class ARG_TYPE>
inline const TYPE* CWHArray<TYPE, ARG_TYPE>::GetData() const
{
return m_pData;
}
//增加元素
template<class TYPE, class ARG_TYPE>
int CWHArray<TYPE, ARG_TYPE>::Add(ARG_TYPE newElement)
{
int nIndex = m_nElementCount;
SetAtGrow(nIndex, newElement);
return nIndex;
}
//拷貝數組
template<class TYPE, class ARG_TYPE>
void CWHArray<TYPE, ARG_TYPE>::Copy(const CWHArray & Src)
{
//效驗參數
ASSERT(this != &Src);
if (this == &Src) return;
//拷貝數組
AllocMemory(Src.m_nElementCount);
if (m_nElementCount>0)
{
for (int i = 0; i<m_nElementCount; i++)
(m_pData + i)->~TYPE();
memset(m_pData, 0, m_nElementCount * sizeof(TYPE));
}
for (int i = 0; i<Src.m_nElementCount; i++)
m_pData[i] = Src.m_pData[i];
m_nElementCount = Src.m_nElementCount;
}
//追加數組
template<class TYPE, class ARG_TYPE>
int CWHArray<TYPE, ARG_TYPE>::Append(const CWHArray & Src)
{
//效驗參數
ASSERT(this != &Src);
if (this == &Src) AfxThrowInvalidArgException();
//拷貝數組
if (Src.m_nElementCount>0)
{
AllocMemory(m_nElementCount + Src.m_nElementCount);
for (int i = 0; i<Src.m_nElementCount; i++)
m_pData[m_nElementCount + i] = Src.m_pData[i];
m_nElementCount += Src.m_nElementCount;
}
return m_nElementCount;
}
//獲取元素
template<class TYPE, class ARG_TYPE>
TYPE & CWHArray<TYPE, ARG_TYPE>::GetAt(int nIndex)
{
//效驗參數
ASSERT(nIndex < m_nElementCount&&nIndex >= 0);
if(nIndex>=m_nElementCount|| nIndex<0)
AfxThrowInvalidArgException();
return m_pData[nIndex];
}
//獲取元素
template<class TYPE, class ARG_TYPE>
const TYPE & CWHArray<TYPE, ARG_TYPE>::GetAt(int nIndex) const
{
//效驗參數
ASSERT(nIndex < m_nElementCount&&nIndex >= 0);
if (nIndex >= m_nElementCount || nIndex<0)
AfxThrowInvalidArgException();
return m_pData[nIndex];
}
//獲取元素
template<class TYPE, class ARG_TYPE>
TYPE & CWHArray<TYPE, ARG_TYPE>::ElementAt(int nIndex)
{
//效驗參數
ASSERT(nIndex < m_nElementCount&&nIndex >= 0);
if (nIndex >= m_nElementCount || nIndex<0)
AfxThrowInvalidArgException();
return m_pData[nIndex];
}
//獲取元素
template<class TYPE, class ARG_TYPE>
const TYPE & CWHArray<TYPE, ARG_TYPE>::ElementAt(int nIndex) const
{
//效驗參數
ASSERT(nIndex < m_nElementCount&&nIndex >= 0);
if (nIndex >= m_nElementCount || nIndex<0)
AfxThrowInvalidArgException();
return m_pData[nIndex];
}
//設置大小
template<class TYPE, class ARG_TYPE>
void CWHArray<TYPE, ARG_TYPE>::SetSize(int nNewSize)
{
//效驗參數
ASSERT(nNewSize >= 0);
if (nNewSize<0) AfxThrowInvalidArgException();
//設置大小
if (nNewSize > m_nElementCount)
{
AllocMemory(nNewSize);
//申請的空間需要new一下 調TYPE的構造
for (INT_PTR i = m_nElementCount; i<nNewSize; i++)
new ((VOID *)(m_pData + i)) TYPE;
}
else
{
//不調析構將會內存泄漏
for (int i = nNewSize; i < m_nElementCount; i++)
(m_pData + i)->~TYPE();
memset(m_pData + nNewSize, 0, (m_nElementCount - nNewSize) * sizeof(TYPE));
}
m_nElementCount = nNewSize;
}
//設置元素
template<class TYPE, class ARG_TYPE>
void CWHArray<TYPE, ARG_TYPE>::SetAt(int nIndex, ARG_TYPE newElement)
{
ASSERT((nIndex >= 0) && (nIndex<m_nElementCount));
if ((nIndex >= 0) && (nIndex<m_nElementCount)) m_pData[nIndex] = newElement;
else AfxThrowInvalidArgException();
return;
}
//設置元素
template<class TYPE, class ARG_TYPE>
void CWHArray<TYPE, ARG_TYPE>::SetAtGrow(int nIndex, ARG_TYPE newElement)
{
//效驗參數
ASSERT(nIndex >= 0);
if (nIndex<0) AfxThrowInvalidArgException();
//設置元素
if (nIndex >= m_nElementCount) SetSize(m_nElementCount + 1);
m_pData[nIndex] = newElement;
return;
}
//插入數據
template<class TYPE, class ARG_TYPE>
void CWHArray<TYPE, ARG_TYPE>::InsertAt(int nIndex, const CWHArray & Src)
{
//效驗參數
ASSERT(nIndex >= 0);
if (nIndex<0) AfxThrowInvalidArgException();
if (Src.m_nElementCount>0)
{
int nCount = Src.m_nElementCount;
//申請數組
if (nIndex<m_nElementCount)
{
int nOldCount = m_nElementCount;
SetSize(m_nElementCount + Src.m_nElementCount);
for (int i = 0; i<nCount; i++) (m_pData + nOldCount + i)->~TYPE();
memmove(m_pData + nIndex + nCount, m_pData + nIndex, (nOldCount - nIndex) * sizeof(TYPE));
memset(m_pData + nIndex, 0, Src.m_nElementCount * sizeof(TYPE));
for (int i = 0; i<Src.m_nElementCount; i++) new (m_pData + nIndex + i) TYPE();
}
else SetSize(nIndex + nCount);
//拷貝數組
ASSERT((nIndex + Src.m_nElementCount) <= m_nElementCount);
int i = 0;
while (nCount--)
m_pData[nIndex++] = Src.m_pData[i++];
}
return;
}
//插入數據
template<class TYPE, class ARG_TYPE>
void CWHArray<TYPE, ARG_TYPE>::InsertAt(int nIndex, ARG_TYPE newElement, int nCount)
{
//效驗參數
ASSERT(nIndex >= 0);
ASSERT(nCount>0);
if ((nIndex<0) || (nCount <= 0)) AfxThrowInvalidArgException();
//申請數組
if (nIndex<m_nElementCount)
{
INT_PTR nOldCount = m_nElementCount;
SetSize(m_nElementCount + nCount);
for (INT_PTR i = 0; i<nCount; i++) (m_pData + nOldCount + i)->~TYPE();
memmove(m_pData + nIndex + nCount, m_pData + nIndex, (nOldCount - nIndex) * sizeof(TYPE));
memset(m_pData + nIndex, 0, nCount * sizeof(TYPE));
for (INT_PTR i = 0; i<nCount; i++) new (m_pData + nIndex + i) TYPE();
}
else SetSize(nIndex + nCount);
//拷貝數組
ASSERT((nIndex + nCount) <= m_nElementCount);
while (nCount--) m_pData[nIndex++] = newElement;
return;
}
//刪除數據
template<class TYPE, class ARG_TYPE>
void CWHArray<TYPE, ARG_TYPE>::RemoveAt(int nIndex, int nCount = 1)
{
//效驗參數
ASSERT(nIndex >= 0);
ASSERT(nCount >= 0);
ASSERT(nIndex + nCount <= m_nElementCount);
if ((nIndex<0) || (nCount<0) || ((nIndex + nCount>m_nElementCount))) AfxThrowInvalidArgException();
//刪除數據
INT_PTR nMoveCount = m_nElementCount - (nIndex + nCount);
for (INT_PTR i = 0; i<nCount; i++) (m_pData + nIndex + i)->~TYPE();
if (nMoveCount>0) memmove(m_pData + nIndex, m_pData + nIndex + nCount, nMoveCount * sizeof(TYPE));
m_nElementCount -= nCount;
return;
}
//刪除元素
template<class TYPE, class ARG_TYPE>
void CWHArray<TYPE, ARG_TYPE>::RemoveAll()
{
if (m_nElementCount>0)
{
for (INT_PTR i = 0; i<m_nElementCount; i++)
(m_pData + i)->~TYPE();
memset(m_pData, 0, m_nElementCount * sizeof(TYPE));
m_nElementCount = 0;
}
return;
}
template<class TYPE, class ARG_TYPE>
TYPE & CWHArray<TYPE, ARG_TYPE>:: operator[](int nIndex)
{
return GetAt(nIndex);
}
template<class TYPE, class ARG_TYPE>
const TYPE & CWHArray<TYPE, ARG_TYPE>:: operator[](int nIndex)const
{
return ElementAt(nIndex);
}
//釋放內存
template<class TYPE, class ARG_TYPE>
void CWHArray<TYPE, ARG_TYPE>::FreeMemory()
{
if(m_nMaxCount>0&&m_pData!=NULL&&m_nMaxCount!=m_nElementCount)
{
//注意這裏不能直接 new TYPE[nNewCount] 否者將會造成野指針
TYPE* pNewData = (TYPE*) new char[(m_nElementCount * sizeof(TYPE))];
memcpy(pNewData, m_pData, sizeof(TYPE)*m_nElementCount);
delete[] m_pData;
m_pData = pNewData;
m_nMaxCount = m_nElementCount;
}
return;
}
//申請內存
template<class TYPE, class ARG_TYPE>
void CWHArray<TYPE, ARG_TYPE>::AllocMemory(int nNewCount)
{
ASSERT(nNewCount > 0);
if (nNewCount > m_nMaxCount)
{
//申請內存
//注意這裏不能直接 new TYPE[nNewCount] 否者將會造成野指針
TYPE* pNewData = (TYPE*) new char[(nNewCount * sizeof(TYPE))];
if (m_pData != NULL)
{
memcpy(pNewData, m_pData, (sizeof(TYPE)*m_nElementCount));
memset(pNewData + m_nElementCount, 0, sizeof(TYPE)*(nNewCount - m_nElementCount));
delete[] m_pData;
}
m_pData = pNewData;
m_nMaxCount = nNewCount;
}
return;
}
#endif
動態數組的封裝管理
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.