C++数组类模板

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

时间: 2024-10-10 14:12:40

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

C++数组类模板(堆内存)

#ifndef _HEAP_ARRAY_H_ #define _HEAP_ARRAY_H_ /* * why * 2016/9/5 15:18 * 实现了一个较完善的数组类模板,在堆空间上 */ template < typename T > class Heap_Array { private: T *m_array; int array_len; Heap_Array(int len);//构造函数 设置一个数组的长度,并且将数组元素值全清0 // Heap_Array(const Hea

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

第10单元 - 单元作业:OJ编程 - 创建数组类模板 查看帮助 返回 温馨提示: 1.本次作业属于Online Judge题目,提交后由系统即时判分. 2.学生可以在作业截止时间之前不限次数提交答案,系统将取其中的最高分作为最终成绩. 本单元作业练习创建模板类.单元作业会涉及冒泡排序.线性查找等算法.如果对排序.查找不熟悉,可以自行baidu或者google 依照学术诚信条款,我保证此作业是本人独立完成的. 1 编写一个数组类模板 Array,能够存储不同类型的数组元素.对数组元素进行查找.

c++数组类模板(栈内存)

#ifndef _ARRAY_H_ #define _ARRAY_H_ /* * 实现一个数组类模板,在栈上 * why * 2016/9/5 */ template < typename T, int N > class Array { private: T m_array[N]; public: int length(); //获取数组长度 bool set_array(T value, int index);  //设置数组元素内容 bool get_array(T& value

数组类模板(四十九)

之前我们学习了类模板,今天我们来看看数组类模板.模板参数可以是数值型参数(非类型参数),如下 使用数值型模板参数是有限制的,如:a> 变量不能作为模板参数:b> 浮点数不能作为模板参数:c> 类对象不能作为模板参数.其本质是模板参数是在编译阶段被处理的单元,因此在编译阶段必须准确无误的唯一确定. 下来我们用函数模板来实现一个面试题:用最高效的方法求 1+2+3+...+N 的值. #include <iostream> #include <string> usin

数组类模板(中)

#ifndef _ARRAY_H_ #define _ARRAY_H_ template < typename T, int N > class Array { T m_array[N]; public: int length(); bool set(int index, T value); bool get(int index, T& value); T& operator[] (int index); T operator[] (int index) const; //数组

c++数组类模板的实现

1.预备知识 (1)模板参数不仅仅可以是类型参数,还可以是数值型参数. 如: template <typename T, int N>//int N就是数值型参数, 要注意这个int类型,因为这里要注意数值型参数的限制,下面有说数值型参数的限制. void func() { T a[N];//使用模板参数来定义局部数组,模板的数值型参数来表示数组的大小. } func<double, 10>();//这样进行使用,数值型参数,也就是第二个参数要是常量,因为这是数值型模板参数的限制造

数组类模板(上)------一种高效的使用

预备知识模板参数可以是数值型参数(非类型参数)template<typename T, int N>void func(){ T a[N]; //使用模板参数定义局部数组}func<double, 10>(); 数值型模板参数的限制-变量不能作为模板参数(变量是不能在编译期就唯一确定的)-浮点数不能作为模板参数(浮点数在计算机内部的表示是不精确的)-类对象不能作为模板参数 ........ 本质:模板参数是在编译阶段被处理的单元,因此,在编译阶段必须准确无误的唯一确定 #inclu

C++——模板、数组类

1.函数模板:可以用来创建一个通用功能的函数,以支持多种不同形参,进一步简化重载函数的函数体设计. 声明方法:template<typename 标识符> 函数声明 求绝对值的模板 #include<iostream>               --编译器从调用abs函数时实参的类型,推导出函数模板的类型参数.using namespace std;             --如该题从调用abs(int)推导出模板中类型参数T为int型. template<typenam

模板类与类模板、函数模板与模板函数等的区别

在C++中有好几个这样的术语,但是我们很多时候用的并不正确,几乎是互相替换混淆使用.下面我想彻底辨清几个术语,这样就可以避免很多概念上的混淆和使用上的错误.这几个词是: 函数指针——指针函数 数组指针——指针数组 类模板——模板类 函数模板——模板函数 最终在使用中,我们就可以让它们实至名归,名正言顺. 1.函数指针——指针函数   函数指针的重点是指针.表示的是一个指针,它指向的是一个函数,例子: int   (*pf)(); 指针函数的重点是函数.表示的是一个函数,它的返回值是指针.例子: