实现Vector<T>(代码)

#pragma once
//迭代器模板  可以使用类模板
#include <exception>
#include <string>
using namespace std;

template<typename T>
class MyVector
{
public:
    /** 迭代器 **/
    class Iterator
    {
        friend class MyVector;
    public:
        Iterator(T* pos) :m_pos(pos)
        {
        }
        Iterator& operator++() //前++
        {
            ++m_pos;
            return *this;
        }
        Iterator operator++(int) //后++
        {
            int* posOld = m_pos;
            ++m_pos;
            return Iterator(posOld);
        }
        Iterator& operator--()//前--
        {
            --m_pos;
            return *this;
        }
        Iterator operator--(int)
        {
            int* posOld = m_pos;
            --m_pos;
            return Iterator(posOld);
        }
        bool operator==(Iterator& itr)
        {
            return (m_pos == itr.m_pos);
        }
        bool operator!=(Iterator& itr)
        {
            return !(*this == itr);
        }
        T& operator*()
        {
            return *m_pos;
        }
        T* operator->()
        {
            return m_pos;
        }
    private:
        T* m_pos = nullptr; //元素位置
    };

public:
    Iterator begin(); //返回指向第一个元素的迭代器
    Iterator end();//返回指向最后一个元素后面位置的迭代器

public:
    MyVector();
    ~MyVector();
    MyVector(const MyVector& obj);

public:
    MyVector& operator=(const MyVector& obj);

public:
    /**增加**/
    void push_back(const T& nVal);

    /*
    * 其他:会抛出异常exception
    */
    Iterator intsert(Iterator itr, const T& nVal);

    /* 修改 */
    T& operator[](int nIdx);
    T& at(int nIdx);

    /* 删除 */
    bool erase(Iterator itr);
    void pop_back();


    /* 查询 */
    Iterator find(const T& nVal);


    /* 其它 */
    int size();

private:
    void CheckCapacity(); //检查内存是否足够放入新的数据

private:
    T*   m_pData = nullptr; //保存数组元素的缓冲区
    int  m_nCapacity = 0;   //整块内存的大小
    int  m_nSize = 0;       //当前内存中有多少数据

private:
    const int m_nInitialCapacityLen = 8; //初始化内存的大小
};

//构造 初始化
template<typename T>
MyVector<T>::MyVector()
{
    m_pData = new T[m_nInitialCapacityLen];
    m_nCapacity = m_nInitialCapacityLen;
    m_nSize = 0;
}


template<typename T>
MyVector<T>::~MyVector()
{
    /*
    * 释放资源
    */
    if (m_pData != nullptr)
    {
        delete[] m_pData;
        m_pData = nullptr;
    }

    m_nSize = 0;
    m_nCapacity = 0;
}

//返回指向第一个元素的迭代器
template<typename T>
typename MyVector<T>::Iterator MyVector<T>::begin()
{
    //数据首地址给m_pos
    return Iterator(m_pData);
}

//返回指向最后一个元素后面位置的迭代器
template<typename T>
typename MyVector<T>::Iterator MyVector<T>::end()
{
    //返回地址为数据末尾最后一个元素位置加一  没有存入新的地址的地方
    return Iterator(m_pData + m_nSize);
}

template<typename T>
MyVector<T>::MyVector(const MyVector& obj)
{
    //拷贝构造函数  这里是浅拷贝
    *this = obj;
}

//等号运算符重载,因为是浅拷贝,所以拷贝构造的时候不能用memcpy;否则类模板释放同一个指针 堆地址重复释放系统会崩
template<typename T>
MyVector<T>& MyVector<T>::operator=(const MyVector& obj)
{
    int i;
    //释放自己
    if (m_pData != nullptr)
    {
        delete[] m_pData;
    }

    //申请新内存
    m_pData = new T[obj.m_nCapacity];
    for (i = 0; i < obj.m_nSize; i++)
    {
        m_pData[i] = obj.m_pData[i];
    }

    m_nSize = obj.m_nSize;
    m_nCapacity = obj.m_nCapacity;

    return *this;
}

/*
增加
*/
template<typename T>
void MyVector<T>::push_back(const T& nVal)
{
    //检查内存大小
    CheckCapacity();

    //存入新的数值
    m_pData[m_nSize] = nVal;
    m_nSize++;
}

template<typename T>
typename MyVector<T>::Iterator MyVector<T>::intsert(Iterator itr, const T& nVal)
{
    /*
    *  获取索引值
    */
    T* pos = itr.m_pos;
    int nIdx = pos - m_pData;


    /*
    * 检查索引是否越界
    */
    if (nIdx < 0 || nIdx > m_nSize)
    {
        throw exception("索引越界");
    }

    /*
    * 检查内存大小
    */
    CheckCapacity();

    /*
    * 拷贝数据
    */
    int nSizeOfCopyData = (m_nSize - nIdx)*sizeof(T);   //拷贝的数据的大小
    T* pBeginPos = m_pData + nIdx;        //拷贝数据的起始位置
    T* pEndPos = m_pData + nIdx + 1;   //拷贝数据的目的位置
    memcpy(pEndPos, pBeginPos, nSizeOfCopyData);

    /*
    *  保存新的数据
    */
    m_pData[nIdx] = nVal;
    m_nSize++;

    return Iterator(&m_pData[nIdx]);
}

/*
修改
*/
template<typename T>
T& MyVector<T>::operator[](int nIdx)
{
    /*
    * 检查索引是否越界
    */
    if (nIdx < 0 || nIdx >= m_nSize)
    {
        throw exception("索引越界");
    }

    return m_pData[nIdx];
}
template<typename T>
T& MyVector<T>::at(int nIdx)
{
    /*
    * 检查索引是否越界
    */
    if (nIdx < 0 || nIdx >= m_nSize)
    {
        throw exception("索引越界");
    }


    return m_pData[nIdx];
}

/*
删除
*/
template<typename T>
bool MyVector<T>::erase(Iterator itr)
{
    /*
    *  获取索引值
    */
    T* pos = itr.m_pos;
    int nIdx = pos - m_pData;

    /*
    * 检查索引是否越界
    */
    if (nIdx < 0 || nIdx >= m_nSize)
    {
        throw exception("索引越界");
    }

    /*
    * 拷贝数据,覆盖被删除的数据
    */
    T* pBeginPos = m_pData + nIdx + 1; //获取拷贝数据的起始位置
    T* pEndPos = m_pData + nIdx;       //获取拷贝数据的目标位置
    int  nSizeOfCopyData = (m_nSize - nIdx - 1)*sizeof(T); //拷贝的数据大小
    memcpy(pEndPos, pBeginPos, nSizeOfCopyData);

    m_nSize--;
    return true;
}
template<typename T>
void MyVector<T>::pop_back()
{
    /*
    * 检查索引是否越界
    */
    if (m_nSize <= 0)
    {
        throw exception("索引越界");
    }

    //删除数据
    m_nSize--;
}

/*
查询
*/
template<typename T>
typename MyVector<T>::Iterator MyVector<T>::find(const T& nVal)
{
    for (int i = 0; i < m_nSize; i++)
    {
        if (nVal == m_pData[i])
        {
            return Iterator(&m_pData[i]);
        }
    }

    return Iterator(nullptr);
}

/*
其它
*/
template<typename T>
int MyVector<T>::size()
{
    return m_nSize;
}

//检查内存是否足够放入新的数据
template<typename T>
void MyVector<T>::CheckCapacity()
{
    //内存不够,申请新内存
    if (m_nSize >= m_nCapacity)
    {
        T* pData = new T[m_nCapacity * 2];              //申请新内存
        memcpy(pData, m_pData, m_nCapacity * sizeof(T));  //拷贝原来的数据
        delete[] m_pData;   //释放原来的额内存
        m_pData = pData;
        m_nCapacity = m_nCapacity * 2;
    }
}

 

posted @ 2020-09-04 08:03  特权E5  阅读(285)  评论(0编辑  收藏  举报