(二)自定義 STL vector模板類 —— MyVector 功能定義

作者的話:我怕我追不上那個被寄予厚望的自己,所有我想努力奔跑


如果沒有看過 MyVector功能聲明,則點擊(一)自定義 vector模板類 —— MyVector 功能聲明

MyVector 方法實現

在同一文件中實現,可以在每個方法前加上 inline

構造、析構實現:

// 構造一個容器,元素個數爲 size 
template <typename T>
inline CMyVector<T>::CMyvector(int size):
    nSize(size), nCapacity(size), pBuff(nullptr)
{
    pBuff = new T[nSize];		// 開闢一段內存

    memset(pBuff, 0, sizeof(T) * size);		// 設置值   清空
}


// 構造一個容器,元素個數爲 size的值爲 elem
template <typename T>
inline CMyVector<T>::CMyVector(int size, const T& elem):
    nSize(size), nCapacity(size), pBuff(nullptr)
{
    pBuff = new T[nSize];

    for(int i = 0; i < size; i++)	// 爲每一個元素賦值 elem
    {
        pBuff[i] = elem;
    }
}


// 複製構造
template <typename T>
inline CMyVector<T>::CMyVector(CMyVector<T> const& that):
    pBuff(nullptr)
{
    nSize = that.nSize;
    nCapacity = that.nCapacity;

    if(nCapacity != 0)		// 容器容量不能爲 0
    {
        pBuff = new T[that.nCapacity];		// 大小要一樣

	// 拷貝數據 
  	memcpy(pBuff, that.pBuff, sizeof(T) * that.nSize);
    }	
}


// 析構
template <typename T>
inline CMyVector<T>::~CMyVector()
{
    this->clear();		// 清空數據
}

運算符重載實現:

// 賦值重載
template <typename T>
inline CMyVector<T>& CMyVector<T>::operator=(CMyVector<T> const& that)
{
    if( this != &that)		// 不能自賦值
    {
       // 臨時存儲拷貝
       T* p_tem = new T[that.nCapacity];	
       memcpy(p_tmp, that.pBuff, sizeof(T) * that.nSize);

       clear();		// 清空原來的內存
       pBuff = p_tmp;	// 接管內存

       nSize = that.nSize;
       nCapacity = that.nCapacity;
    }

    return *this;
}


//  == 重載
template<typename T>
inline bool CMyVector::operator==(CMyVector<T> const& that)
{
    if(nSize != that.nSize)	// 長度不相等 直接false
        return false;

    for(size_t i = 0; i < nSize; i++)	// 判斷每一個元素
    {
        if(pBuff[i] != that.pBuff[i])
             return false;
    }
 
    return true;
}


//  !=  重載
template <typename T>
inline bool CMyVector<T>::operator != (CMyVector<T> const& that)
{
    return !(*this == that);		//  代碼重用
}


// []  重載
template <typename T>
inline T& CMyVector<T>::operator[](int index) const
{
     return pBuff[index];			// 不判斷越界問題
}

無參功能方法實現:

// 釋放內存
template<typename T>
inline void CMyVector<T>::clear()
{
    if(pBuff)			// 不爲空  delete 釋放內存
    {
        delete[] pBuff;
    }
    
    pBuff = nullptr;		// 可能會用到 指向 空

    nSize = 0;
    
    // 容量大小不需要改爲 0
}


// 元素大小
template <typename T>
inline size_t CMyVector<T>::size() const		
{
    return nSize;
}


// 容量大小
template <typename T>
inline size_t CMyVector<T>::capacity() const
{
    return nCapacity;
}


// 判斷是否爲空
template <typename T>
inline bool CMyVector<T>::empty() const
{
    return nSiz == 0;
}
 
 
// 返回每一個元素
template <typename T>
inline T& CMyVector<T>::front()
{
    return pBuff[0];
}


// 返回最後一個元素
template <typename T>
inline T& CMyVector<T>::back()
{
    return pBuff[nSize - 1];
}

有參功能方法實現:

// 複製 n個elem 賦值給this   可以理解成 浴火重生
template <typename T>
inline void CMyVector<T>::assign(int n,const T& elem)
{
    clear();		// 清空原先的數據

    nSize = nCapacity = n;	// 重新設置數據
    pBuff = new T[n];		// 開闢 n個T型 內存

    for(size_t i = 0; i < n; i++)
    {
        pBuff[i] = elem;
    }
}


// 交換數據
template <typename T>
inline void CMyVector<T>::swap(CMyVector<T>& that)
{
    CMyVector<T> temp;

    temp = *this;	// 代碼重用
    *this = that;
    that = temp;
}


// 擴充數組數組容量,不能改小
template <typename T>
inline void CMyVector<T>::reserve(int n)
{
    if(n > nCapacity)			// 判斷 是否需要擴容
    {
        T* tempBuff = new T[n];		// 開闢一個臨時內存
        
        memcpy(tempBuff, pBuff, sizeof(T) * nSize);  // 拷貝數據到臨時內存中
      
        if(pBuff)			// 清空原先的內存數據
            delete[] pBuff;

        pBuff = tempBuff;		// 接管內存
        
        nCapacity = n;			// 容量大小爲擴容的大小
    }
}


// 改變元素個數    改大用擴容	改小用 nSize = n
template <typename T>
inline void CMyVector<T>::resize(int n)
{
    if(n > nSize)		// 判斷大小
    {
        reserve(n);		// 擴容

	// 設置後加的數據爲 0
        memset(&pBuff[nSize], 0, sizeof(T) * (n - nSize));
    }

    nSize = n;		// 不管是大於數組容量   還是小於數據原本元素個數  
}


// 改變元素個數,多的值爲 elem
inline void CMyVector<T>::resize(int n, const T& elem)		// 和上面的方法差不多
{
    if(n > nSize)
    {
        reverse(n);		// 擴容
       
        for(size_t i = nSize; i < n; i++)	// 後加的元素設置爲 elem
        {
            pBuff[i] = elem;
        }
    }

    nSize = n;		
}


// 返回下標 index,越界拋出 out_of_range 異常
template <typename T>
inline T& CMyVector<T>::at(int index) const
{
    if(index >= 0 && index < nSize)	// 限制範圍
    {
        return pBuff[index];	
    }

    throw "out_of_range";		// 越界  拋出異常
}


// 刪除最後一個數據
template <typename T>
inline void CMyVector<T>::pop_back()
{
    if(nSize > 0)
    {
        nSize--;		// 告訴編譯器,我不管了,你管去
    }
}


// 最重要的一個方法實現
// 從後面插入數據
template <typename T>
inline void CMyVector<T>::push_back(const T& elem)
{
    if( nSize == nCapacity)		// 容量不夠了  告訴編譯器 需要擴容了
        reserve(2 * nCapacity + 1);	// 此處擴容 兩倍 + 1	+ 1 的原因是防止有0 的情況

    pBuff[nSize++] = elem;
}

到此處,我們的MyVector 已經完成的差不多了,可以在 主函數中正常的使用。 此文章就不在演示了。


提前祝大家新年快樂 ^ - ^

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