動態數組的封裝管理

#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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章