首页 > 代码库 > 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源代码实现
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。