天上飞来一只 发表于 2020-10-23 10:33

C++迭代器模拟代码(学习记录)

本帖最后由 天上飞来一只 于 2020-10-23 11:37 编辑

学习使用,没大规模测试,通用改模板
留点分,谢谢!

#include <memory.h>#include <stdexcept>
#include <assert.h>

class CArrary
{
public:
      //迭代器类,保护成员
      class iterator
      {
      public:
                iterator& operator++()
                {
                        assert(m_data != m_end);
                        m_data++;
                        return *this;
                }
                iterator& operator--()
                {
                        assert(m_data != m_begin);
                        m_data--;
                        return *this;
                }
                iterator operator++(int)
                {
                        assert(m_data != m_end);
                        //------注意,临时变量保存,在构造
                        char* temp = m_data;
                        m_data++;
                        return iterator(temp, m_begin, m_end);
                }
                iterator operator--(int)
                {
                        assert(m_data != m_begin);
                        //------注意,临时变量保存,在构造
                        char* temp = m_data;
                        m_data--;
                        return iterator(temp, m_begin, m_end);
                }
                char& operator*()
                {
                        return *m_data;
                }
                bool operator==(const iterator& itr)
                {
                        return m_data == itr.m_data;
                }
                bool operator!=(const iterator& itr)
                {
                        return m_data != itr.m_data;
                }

      private:
                friend class CArrary;
                //私有构造器,只能通过公共方法获取
                iterator(char *data, char *begin, char *end)
                {
                        m_data = data;
                        m_begin = begin;
                        m_end = end;
                }
      private:
                char* m_data;//保护的数据
                char* m_begin;//开始数据
                char* m_end;//结束
      };
      //类外iterator成员方法
public:
      //必须有 begin end
      //----------注意,头与尾,必须越界,这样++判断是否越界
      iterator begin()
      {
                return iterator(m_pBuff, m_pBuff - 1, m_pBuff + m_nElementSize);
      }
      iterator end()
      {
                return iterator(m_pBuff + m_nElementSize, m_pBuff - 1, m_pBuff + m_nElementSize);
      }
public:
      CArrary();
      //直接深拷贝
      CArrary(const CArrary& ary);
      virtual ~CArrary();

public:
      //初始化
      void InitFun();
      //增加
      bool AddHead(int val);
      bool AddTail(int val);
      bool Insert(int nIdx, int val);
      //--------------重载迭代器,待完成
      bool Insert(iterator itr, int val)
      {
                //利用数组的连续性,求长度
                /*
                int arr = { 0 };
                int i = &arr - arr;
                cout << i<< endl;
                */
                int nIndex = itr.m_data - m_pBuff;
                Insert(nIndex, val);
      }
      //删除
      bool RemoveHead();
      bool RemoveTail();
      bool Remove(int nIdx);
      //--------------重载迭代器,待完成
      bool Remove(iterator itr)
      {
                int nIndex = itr.m_data - m_pBuff;
                Remove(nIndex);
      }

      //修改
      bool SetVal(int nIdx, int val);
      //--------------重载迭代器,待完成
      bool SetVal(iterator itr, int val) {}
      char&operator[](int nIdx);//此处会抛出异常
      CArrary& operator+=(const CArrary& ary);
      CArrary& operator=(const CArrary& ary);//直接深拷贝

                                                                                 //查询
      int Find(int val);

      //获取数组元素的个数
      int Size()const;

      //清空
      void Clear();

private:
      char *m_pBuff;            //存放数组元素的缓冲区
      int   m_nBuffSize;      //缓冲区的大小
      int   m_nElementSize;      //数组中元素的个数
};

void CArrary::InitFun()
{
   m_pBuff = nullptr;
   m_nElementSize = 0;
   m_nBuffSize = 0;
}

CArrary::CArrary()
{
      
   InitFun();
}


CArrary::CArrary(const CArrary& ary)
{
      //初始化,防止没有调用构造函数;
      InitFun();
      *this = ary;
}


CArrary::~CArrary()
{
      Clear();
}


bool CArrary::AddHead(int val)
{
      return Insert(0, val);
}

bool CArrary::AddTail(int val)
{
      return Insert(m_nElementSize, val);
}


bool CArrary::Insert(int nIdx, int val)
{
      //判断是否为空
      if (m_pBuff == nullptr)
      {
                const int nInitBuffSize = 4;
                m_nBuffSize = nInitBuffSize;
                m_pBuff = new char;
                m_nElementSize = 0;
      }

      //判断索引值是否合理
      if (nIdx < 0 || nIdx > m_nElementSize)
      {
                return false;
      }

      //判断缓冲区是否足够
      if (m_nElementSize >= m_nBuffSize)
      {
                //申请新的缓冲区
                m_nBuffSize = m_nBuffSize * 2; //原缓冲区扩大两倍
                char* pNewBuff = new char;
                memcpy(pNewBuff, m_pBuff, m_nElementSize * sizeof(char)); //拷贝原来的数据
                delete[]m_pBuff; //删除原来的缓冲区
                m_pBuff = pNewBuff;
      }

      //添加新的元素
      //从nIdx开始的元素都向后移动
      memcpy(&m_pBuff, &m_pBuff, (m_nElementSize - nIdx) * sizeof(char));
      m_pBuff = val;
      m_nElementSize++;

      return true;
}


bool CArrary::RemoveHead()
{
      return Remove(0);
}


bool CArrary::RemoveTail()
{
      return Remove(m_nElementSize - 1);
}


bool CArrary::Remove(int nIdx)
{
      //数组为空则不删除判断索引值是否合理
      if (m_pBuff == nullptr || nIdx < 0 || nIdx >= m_nElementSize)
      {
                return false;
      }

      //删除元素
      memcpy(&m_pBuff,
                &m_pBuff,
                (m_nElementSize - nIdx - 1) * sizeof(char));
      m_nElementSize--;

      return true;
}


bool CArrary::SetVal(int nIdx, int val)
{
      //判断索引值是否合理
      if (nIdx < 0 || nIdx >= m_nElementSize)
      {
                return false;
      }

      //修改
      m_pBuff = val;

      return true;
}


char&CArrary::operator[](int nIdx)
{
      //判断索引值是否合理
      if (nIdx < 0 || nIdx >= m_nElementSize || m_pBuff == nullptr)
      {
                throw std::out_of_range("访问越界");
      }

      return m_pBuff;
}

CArrary& CArrary::operator+=(const CArrary & ary)
{
      //如果对方为空, 则不拼接
      if (ary.m_pBuff == nullptr)
      {
                return *this;
      }

      //如果自己为空,则直接拷贝
      if (m_pBuff == nullptr)
      {
                *this = ary;
                return *this;
      }

      //申请新的内存, 拷贝数据

      char* pNewBuff = new char;

      //防止元素是指针、地址的情况
      for (int i = 0; i < m_nElementSize; i++)
      {
                pNewBuff = m_pBuff;
      }
      for (int i = 0; i < ary.m_nElementSize; i++)
      {
                pNewBuff = ary.m_pBuff;
      }
      //memcpy(pNewBuff, m_pBuff, m_nElementSize * sizeof(T));
      //memcpy(pNewBuff + m_nElementSize, ary.m_pBuff, ary.m_nElementSize * sizeof(T));

      delete[] m_pBuff;
      m_pBuff = pNewBuff;
      m_nBuffSize += ary.m_nBuffSize;
      m_nElementSize += ary.m_nElementSize;
      return *this;
}


CArrary& CArrary::operator=(const CArrary & ary)
{
      //自己赋值自己, 不做任何操作
      if (this == &ary)
      {
                return *this;
      }
      //拷贝目标对象的数据到自己
      m_pBuff = new char;
      //防止元素是指针、地址的情况
      for (int i = 0; i < ary.m_nElementSize; i++)
      {
                m_pBuff = ary.m_pBuff;
      }
      m_nElementSize = ary.m_nElementSize;
      m_nBuffSize = ary.m_nBuffSize;

      return *this;
}


int CArrary::Find(int val)
{
      for (int i = 0; i < m_nElementSize; i++)
      {
                if (m_pBuff == val)
                {
                        return i;
                }
      }

      return -1;
}


int CArrary::Size() const
{
      return m_nElementSize;
}


void CArrary::Clear()
{
      if (m_pBuff != nullptr)
      {
                delete[] m_pBuff;
                m_pBuff = nullptr;
                m_nBuffSize = 0;
                m_nElementSize = 0;
      }
}

284406022 发表于 2020-10-23 11:01

CArrary这个类测试过吗?稳定不?

sjh52pojie 发表于 2020-10-23 11:21

只能操作int么,能否给个通用的

天上飞来一只 发表于 2020-10-23 11:36

sjh52pojie 发表于 2020-10-23 11:21
只能操作int么,能否给个通用的

通用 改 模板
页: [1]
查看完整版本: C++迭代器模拟代码(学习记录)