首页 > 代码库 > STL 之 vector源代码实现

STL 之 vector源代码实现

一:vector异常类 Myexcep.h

#include<string>
#include<iostream>
using namespace std;

class Myexcep
{
    public:
        Myexcep() :m_exnote("Get a exception ") {}
        Myexcep(const string &other){m_exnote = other;}
        virtual ~Myexcep(){}
        virtual void show_message() {cout << m_exnote <<endl;}
    private:
        string m_exnote;
};

class Outofbond :public Myexcep
{
    public:
        Outofbond() :m_outnote("Get a Out of bond exception ") {}
        Outofbond(const string &other){m_outnote = other;}
        ~Outofbond(){}
        void show_message(){cout << m_outnote <<endl;}
    private:
        string m_outnote;
};

class Allocfail :public Myexcep
{
    public:
        Allocfail():m_alonote("Get a Allocate fail exception "){}
        Allocfail(const string &other){m_alonote = other;}
        ~Allocfail(){}
        void show_message(){cout << m_alonote <<endl;}
    private:
        string m_alonote;
};

二:vector 类的代码 vec.h

#ifndef VEC_H_H
#define VEC_H_H
#include "Myexce.h"
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cassert>
using namespace std;

template <class T>
class Vec
{
    public:
        typedef T* iterator;
        typedef const T* const_iterator;
        typedef size_t size_type;
        typedef T value_type;
    public:
        Vec();
        Vec(size_type,const T&);
        Vec(const Vec &);
        Vec& operator=(const Vec&);
        ~Vec();//调用相应的create()和uncreate()函数

        T& operator[](size_type index);
        const T& operator[](size_type index) const;// 运算符重载

        void push_back(const T&);
        void pop_back();
        void erase(const size_type&);//根据下标删除元素,push_back()调用了grow()
        size_type size() const        {return (m_finished - m_start);}
        iterator begin()              {return m_start;}
        const_iterator begin() const {return m_start;}

        iterator end()                {return m_finished;}
        const_iterator end() const    {return m_finished;}
    private:
        void create();
        void create(size_type,const T&);
        void create(const_iterator,const_iterator);//调用allocate()申请空间,并调用init_fill(),init_copy()进行初始化
        void uncreate();
        T* allocate(size_type);
        void init_fill(iterator,iterator,const T&);
        void init_copy(const_iterator,const_iterator,iterator);
        void grow();// 调用了size(),和 max()
        void append_element(const T&);
    private:
       iterator m_start;
       iterator m_finished;
       iterator m_limit;// 有这么多指针,肯定有深拷贝
};
#endif

三 vec.h 的实现和main 函数 Vec,cpp

//---------------------vec.cpp-------------
#include "vec.h"
/**** constructor ****/
template <class T>
Vec<T>::Vec()
{
    create();
}
template <class T>
Vec<T>::Vec(size_type sz,const T& val)
{
create(sz,val);
}
template <class T>
Vec<T>::Vec(const Vec &rhs)
{
create(rhs.begin(),rhs.end());
}

template <class T>
Vec<T>& Vec<T>::operator=(const Vec& rhs)
{
   if(&rhs == this)
    return *this;
   uncreate();
   create(rhs.begin(),rhs.end());
   return *this;
}
template <class T>
Vec<T>::~Vec()
{
    uncreate();
}
/**** we have a create function to inital the data ****/
template <class T>
void Vec<T>::create()
{
    m_start = m_finished = m_limit = NULL;
}

template <class T>
void Vec<T>::create(size_type sz,const T&val)
{
    m_start = allocate(sz);
    m_finished = m_limit = m_start+sz;
    init_fill(m_start,m_limit,val);
}
template <class T>
void Vec<T>::create(const_iterator first,const_iterator end)
{
   size_type sz = end - first;
   m_start = allocate(sz);
   m_finished = m_limit = m_start+sz;
   init_copy(first,end,m_start);
}
template <class T>
void Vec<T>::uncreate()
{
    iterator iter = m_start;
    iterator end = m_limit;
    for(; iter != end; )
    {
        iterator next_iter = iter + 1;
       delete(iter);
       iter = next_iter;
    }
    m_start = m_finished =m_limit =0;

}

/**** we define a function to allocate memory ****/
template <class T>
T* Vec<T>::allocate(size_type sz)
{
   T* t = new T[sizeof(T) * sz];
   if(!t)
   {
      throw Allocfail();
   }

   return t;
}
template <class T>
void Vec<T>::init_fill(iterator data,iterator limit,const T& val)
{
   iterator iter = data;
   iterator end   = limit;

   for(; iter != end; iter++)
   {
    *iter = val;
   }
}
template <class T>
void Vec<T>::init_copy(const_iterator first,const_iterator end,iterator lhs)
{
    copy(first,end,lhs);// copy的实现暂时没有找到呢。。。
}
//  STL algorithm之copy template <class InputIterator, class OutputIterator> OutputIterator copy ( InputIterator first, InputIterator last, OutputIterator result );
//作用:将[first, last)范围的元素,拷贝到以result开始的范围内。类似于:memcopy()
/**** overload operator [] ****/
template <class T>
T& Vec<T>::operator[](size_type index)
{
    if(index >= size())
    {
         throw Outofbond();
    }
    return m_start[index];
}
template <class T>
const T& Vec<T>::operator[](size_type index) const
{
    if(index >= size())
    {
        throw Outofbond();
    }
    return m_start[index];
}
/**** push_back ,pop_back,erase ****/
template <class T>
void Vec<T>::push_back(const T& val)
{
    if(m_finished == m_limit)
          grow();
    append_element(val);
}
template <class T>
void Vec<T>::pop_back()
{
    if(size() == 0)
       return ;
    m_finished--;

}
template <class T>
void Vec<T>::erase(const size_type& ipos)
{
    if(ipos <0 || ipos >size())
    {
        throw Outofbond();
    }
    size_type iend = size()-1;
    size_type i = ipos;

    for(;i >= ipos && i < iend ; i++)
    {
        m_start[i] = m_start[i+1];
    }// 后面的元素依次向前移动,只能删除一个
    m_finished--;
}
template <class T>
void Vec<T>::append_element(const T& val)
{
    assert(m_finished!=m_start);
    *m_finished++ = val;
}
inline size_t max(const size_t lhs,const size_t rhs)
{
    return lhs > rhs ? lhs:rhs;
}
template <class T>
void Vec<T>::grow()
{
    size_type new_size = max( 2*size(), 1);
    iterator new_start = allocate(new_size);
    iterator new_limit = new_start + new_size;
    iterator new_finished = new_start + size();

    init_copy(begin(),end(),new_start);
    uncreate();
    m_start = new_start;
    m_finished = new_finished;
    m_limit = new_limit;
}
/**** output the vector ****/
template <class T>
ostream& operator<<(ostream &os, const Vec<T> &me)
{
    const T* iter = me.begin();     //Is "const T*" replaced by "const_iterator"?
    for(;iter != me.end(); iter++)
    {
       os << *iter <<", ";
    }
    return os;
}

/**** test the case ****/
int main()
{
    try
    {
        cout << "Test begin: " << endl;

        Vec<int> v1(4,3);
        cout << "After v1(4,3), v1[3]: " << v1[3] <<endl;

        Vec<int> v2(v1);
        cout << "After v2(v1), v2--value: " << v2 <<endl;

        Vec<int> v3;
        v3 = v2;
        cout << "After v3=v2,   v3--value: " << v3 <<endl;
        v3.pop_back();
        cout << "After v3.pop_back(),   v3--value: " << v3 <<endl;

        v3.push_back(5);
        cout << "After v3.push_back(5), v3--value: " << v3 <<endl;


        Vec<double> v4(5, 222.2);
        cout << "After v4(5,222.2),v4--value:" << v4 << endl;

        Vec<char> v5(5, 'a');
        cout << "After v5(5,222.2),v5--value:" << v5 << endl;

        string aa = "hi world";
//        string bb = aa;
//        cout << bb << endl;
        Vec<string> v6(5, aa);
        v6.push_back("hello 好");
        cout << v6 << endl;

        Vec<string> v7;
        v7 = v6;
        cout << v7[4] << endl;

        v3.erase(2);
        cout << "After v3.erase(2), v3--value: " << v3 <<endl;
        cout << "After v3.erase(2), v3--value: " << v3[6] <<endl;

    }

    catch(Outofbond e)
    {
       e.show_message();
       exit(-1);
    }
    catch(Allocfail e){
       e.show_message();
       exit(-1);
    }
    return 0;
}

四 知识补充 —— vector类常用的函数如下所示:

 vector类称作向量类,它实现了动态数组,用于元素数量变化的对象数组。像数组一样,vector类也用从0开始的下标表示元素的位置;但和数组不同的是,当vector对象创建后,数组的元素个数会随着vector对象元素个数的增大和缩小而自动变化。

 1.构造函数

  • vector():创建一个空vector
  • vector(int nSize):创建一个vector,元素个数为nSize
  • vector(int nSize,const t& t):创建一个vector,元素个数为nSize,且值均为t
  • vector(const vector&):复制构造函数
  • vector(begin,end):复制[begin,end)区间内另一个数组的元素到vector
2.增加函数
  • void push_back(const T& x):向量尾部增加一个元素X
  • iterator insert(iterator it,const T& x):向量中迭代器指向元素前增加一个元素x
  • iterator insert(iterator it,int n,const T& x):向量中迭代器指向元素前增加n个相同的元素x
  • iterator insert(iterator it,const_iterator first,const_iterator last):向量中迭代器指向元素前插入另一个相同类型向量的[first,last)间的数据 
3.删除函数
  • iterator erase(iterator it):删除向量中迭代器指向元素
  • iterator erase(iterator first,iterator last):删除向量中[first,last)中元素
  • void pop_back():删除向量中最后一个元素
  • void clear():清空向量中所有元素  
4.遍历函数
  • reference at(int pos):返回pos位置元素的引用
  • reference front():返回首元素的引用
  • reference back():返回尾元素的引用
  • iterator begin():返回向量头指针,指向第一个元素
  • iterator end():返回向量尾指针,指向向量最后一个元素的下一个位置
  • reverse_iterator rbegin():反向迭代器,指向最后一个元素
  • reverse_iterator rend():反向迭代器,指向第一个元素之前的位置
5.判断函数
  • bool empty() const:判断向量是否为空,若为空,则向量中无元
6.大小函数
  • int size() const:返回向量中元素的个数
  • int capacity() const:返回当前向量张红所能容纳的最大元素值
  • int max_size() const:返回最大可允许的vector元素数量值
7.其他函数
  • void swap(vector&):交换两个同类型向量的数据
  • void assign(int n,const T& x):设置向量中第n个元素的值为x
  • void assign(const_iterator first,const_iterator last):向量中[first,last)中元素设置成当前向量元素
 



STL 之 vector源代码实现