C++数组类模板

核能气质少年 提交于 2020-01-03 10:11:45

 * 作为数组类模板,肯定没有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;
};


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!