目录
后记:●由于作者水平有限,文章难免存在谬误之处,敬请读者斧正,俚语成篇,恳望指教! ——By 作者:新晓·故知
对于STL标准库中stack、queue、priority_queue及反向迭代器的模拟实现,简单实现常用函数接口,了解并学习迭代器的适配以及反向迭代器用到的迭代器萃取技术,模拟实现综合性高,这里只进行学习了解,具体可参见STL源码。
1.模拟实现stack:
简单实现常用函数接口:push、pop、top、size、empty等,附用deque等。(1)stack.h:
#pragma once #include<iostream> #include<deque> #include<vector> #include<list> #include<string> using namespace std; namespace my { template<class T, class Container = deque<T>> class stack { public: void push(const T& x) { _con.push_back(x); } void pop() { _con.pop_back(); } const T& top() { return _con.back(); } size_t size() { return _con.size(); } bool empty() { return _con.empty(); } private: Container _con; }; }
(2)test.cpp:
#include"Stack.h" void test_stack() { my::stack<int> s; //附用std::deque //my::stack<int, std::vector<int>> s; //附用std::vector //my::stack<int, std::list<int>> s; //附用std::list //my::stack<int, std::string> s; //附用std::string,数据过大会存在截断数据丢失 s.push(1); s.push(2); s.push(3); s.push(4); s.push(500); while (!s.empty()) { cout << s.top() << " "; s.pop(); } cout << endl; } int main() { test_stack(); return 0; }
#include<deque> namespace byte { template<class T, class Con = deque<T>> //template<class T, class Con = vector<T>> //template<class T, class Con = list<T>> class stack { public: stack() {} void push(const T& x) { _c.push_back(x); } void pop() { _c.pop_back(); } T& top() { return _c.back(); } const T& top()const { return _c.back(); } size_t size()const { return _c.size(); } bool empty()const { return _c.empty(); } private: Con _c; }; }
2. 模拟实现queue
简单实现常用函数接口:push、pop、front、back、size、empty等,附用deque、list等。
(1)Queue.h:
#pragma once #include<iostream> #include<queue> #include<deque> #include<vector> #include<list> #include<string> using namespace std; namespace my { template<class T,class Container =deque<T>> class queue { public: void push(const T& x) { _con.push_back(x); } void pop() { _con.pop_front(); } const T& front() { return _con.front(); } const T& back() { return _con.back(); } size_t size() { return _con.size(); } bool empty() { return _con.empty(); } private: Container _con; }; }
(2)test.cpp:
#include"Queue.h" void test_queue() { my::queue<int> q; //附用std::deque //my::queue<int, std::list<int>> q; //附用std::list q.push(1); q.push(2); q.push(3); q.push(4); while (!q.empty()) { cout << q.front() << " "; q.pop(); } cout << endl; } int main() { test_queue(); return 0; }
#include<deque> #include <list> namespace byte { template<class T, class Con = deque<T>> //template<class T, class Con = list<T>> class queue { public: queue() {} void push(const T& x) { _c.push_back(x); } void pop() { _c.pop_front(); } T& back() { return _c.back(); } const T& back()const { return _c.back(); } T& front() { return _c.front(); } const T& front()const { return _c.front(); } size_t size()const { return _c.size(); } bool empty()const { return _c.empty(); } private: Con _c; }; }
3.模拟实现priority_queue:
简单实现常用函数接口:push、pop、top、size、empty等,附用deque等。对于priority_queue模拟实现,还涉及仿函数less 、greater调整优先级,建立堆以及堆的调整,综合性高。
(1)priority_queue:
#pragma once #include<iostream> #include<queue> #include<deque> #include<vector> #include<list> #include<string> #include<cassert> using namespace std; //仿函数版1 //namespace my //{ // A // 仿函数/函数对象 --对象可以像调用函数一样去使用 // //struct less // //{ // // bool operator()(int x, int y) // // { // // return x < y; // // } // //}; // // //可比较不同类型,int,double等 // //仿函数less // template<class T> // struct less // { // bool operator()(const T& x, const T& y) const // { // return x < y; // } // }; // //仿函数greater // template<class T> // struct greater // { // bool operator()(const T& x, const T& y) const // { // return x > y; // } // }; // //仿函数可以替代函数指针 // // //优先级队列: 大堆用< 小堆用> // template<class T, class Container = vector<T>,class Compare=less<T>> // class priority_queue // { // public: // void AdjustUp(int child) // { // Compare comFunc; // int parent = (child - 1) / 2; // while (child > 0) // { // //if (_con[parent] < _con[child]) // if(comFunc(_con[parent], _con[child])) //if (comFunc.operator()(_con[parent], _con[child])) // { // swap(_con[parent], _con[child]); // child = parent; // parent = (child - 1) / 2; // } // else // { // break; // } // } // } // void push(const T& x) // { // _con.push_back(x); // AdjustUp(_con.size() - 1); // // } // void AdjustDown(int parent) // { // Compare comFunc; // // size_t child = parent * 2 + 1; // while (child<_con.size()) // { // //if (child + 1 < _con.size() && _con[child] < _con[child + 1]) // if (child + 1 < _con.size() &&comFunc(_con[child], _con[child + 1])) // { // ++child; // } // //if (_con[parent]<_con[child]) // if (comFunc(_con[parent] ,_con[child])) // { // swap(_con[parent], _con[child]); // parent = child; // child = parent * 2 + 1; // } // else // { // break; // } // } // } // void pop() // { // assert(!_con.empty()); // swap(_con[0], _con[_con.size() - 1]); // _con.pop_back(); // // AdjustDown(0); // } // const T& top() // { // return _con[0]; // } // size_t size() // { // return _con.size(); // } // bool empty() // { // return _con.empty(); // } // private: // Container _con; // }; //} 函数指针版 //namespace my //{ // bool ComIntLess(int x1, int x2) // { // return x1 > x2; // } // //仿函数less // template<class T> // struct less // { // bool operator()(const T& x, const T& y) const // { // return x < y; // } // }; // //仿函数greater // template<class T> // struct greater // { // bool operator()(const T& x, const T& y) const // { // return x > y; // } // }; // // //template<class T, class Container = vector<T>, class Compare = less<T>> // template<class T, class Container = vector<T>, class Compare = less<T>> // // class priority_queue // { // public: // priority_queue(const Compare& comFunc = Compare()) // :_comFunc(comFunc) // // {} // void AdjustUp(int child) // { // //Compare comFunc; // int parent = (child - 1) / 2; // while (child > 0) // { // //if (_con[parent] < _con[child]) // if (_comFunc(_con[parent], _con[child])) //if (comFunc.operator()(_con[parent], _con[child])) // { // swap(_con[parent], _con[child]); // child = parent; // parent = (child - 1) / 2; // } // else // { // break; // } // } // } // void push(const T& x) // { // _con.push_back(x); // AdjustUp(_con.size() - 1); // // } // void AdjustDown(int parent) // { // Compare comFunc; // // size_t child = parent * 2 + 1; // while (child < _con.size()) // { // //if (child + 1 < _con.size() && _con[child] < _con[child + 1]) // if (child + 1 < _con.size() && _comFunc(_con[child], _con[child + 1])) // { // ++child; // } // //if (_con[parent]<_con[child]) // if (_comFunc(_con[parent], _con[child])) // { // swap(_con[parent], _con[child]); // parent = child; // child = parent * 2 + 1; // } // else // { // break; // } // } // } // void pop() // { // assert(!_con.empty()); // swap(_con[0], _con[_con.size() - 1]); // _con.pop_back(); // // AdjustDown(0); // } // const T& top() // { // return _con[0]; // } // size_t size() // { // return _con.size(); // } // bool empty() // { // return _con.empty(); // } // private: // Compare _comFunc; // Container _con; // }; //} //仿函数版2 namespace my { A 仿函数/函数对象 --对象可以像调用函数一样去使用 //struct less //{ // bool operator()(int x, int y) // { // return x < y; // } //}; //可比较不同类型,int,double等 //仿函数less template<class T> struct less { bool operator()(const T& x, const T& y) const { return x < y; } }; //仿函数greater template<class T> struct greater { bool operator()(const T& x, const T& y) const { return x > y; } }; //仿函数可以替代函数指针 //优先级队列: 大堆用< 小堆用> template<class T, class Container = vector<T>, class Compare = less<T>> class priority_queue { public: priority_queue(const Compare& comFunc = Compare()) :_comFunc(comFunc) {} template <class InputIterator> priority_queue(InputIterator first, InputIterator last, const Compare& comFunc = Compare()) :_comFunc(comFunc) { while (first != last) { _con.push_back(*first); ++first; } //建堆(倒着建) for (int i = (_con.size() - 1 - 1) / 2; i >= 0; --i) { AdjustDown(i); } } void AdjustUp(int child) { Compare comFunc; int parent = (child - 1) / 2; while (child > 0) { //if (_con[parent] < _con[child]) if (comFunc(_con[parent], _con[child])) //if (comFunc.operator()(_con[parent], _con[child])) { swap(_con[parent], _con[child]); child = parent; parent = (child - 1) / 2; } else { break; } } } void push(const T& x) { _con.push_back(x); AdjustUp(_con.size() - 1); } void AdjustDown(int parent) { Compare comFunc; size_t child = parent * 2 + 1; while (child < _con.size()) { //if (child + 1 < _con.size() && _con[child] < _con[child + 1]) if (child + 1 < _con.size() && comFunc(_con[child], _con[child + 1])) { ++child; } //if (_con[parent]<_con[child]) if (comFunc(_con[parent], _con[child])) { swap(_con[parent], _con[child]); parent = child; child = parent * 2 + 1; } else { break; } } } void pop() { assert(!_con.empty()); swap(_con[0], _con[_con.size() - 1]); _con.pop_back(); AdjustDown(0); } const T& top() { return _con[0]; } size_t size() { return _con.size(); } bool empty() { return _con.empty(); } private: Compare _comFunc; Container _con; }; }
(2)test.cpp:
#include"priority_queue.h" //仿函数版1测试 //void test_priority_queue() //{ // //问题:优先级队列(priority_queue)默认大的优先级高,但传的是less仿函数<,底层是一个大堆 // //如果想切换成小的优先级高,则传greater仿函数,底层是一个小堆, // //这种设计是反过来的,设计有些违反常规 // //my::priority_queue<int> pq; //默认是大堆 less比较< // my::priority_queue<int, std::vector<int>, my::greater<int>> pq; //greater<int> 仿函数,默认小的优先级高,这里为小堆 // pq.push(6); // pq.push(4); // pq.push(7); // pq.push(3); // pq.push(1); // pq.push(9); // while (!pq.empty()) // { // cout << pq.top() << " "; // pq.pop(); // } // cout << endl; //} //仿函数less测试 //这个测试对应于A void test_less_function() { my::less LessCom; cout << LessCom(6, 9) << endl; //lessCom是一个less对象,less是仿函数, } 仿函数less测试 这个测试对应于templ //void test_function() //{ // //可比较不同类型,int,double等 // my::less<int> LessCom; // cout << LessCom(6, 9) << endl; //LessCom是less的对象,虽然看着像函数调用,但其实是对象 // // my::greater<double> GreaterCom; // cout << GreaterCom(1.1, 5.4) << endl; //} //int main() //{ // test_priority_queue(); // //test_less_function(); // //test_function(); // return 0; //} //函数指针版测试 //void test_priority_queue() //{ // bool my::ComIntLess(int x1, int x2); // //my::priority_queue<int> pq; // //my::priority_queue<int, std::vector<int>, my::greater<int>> pq; // my::priority_queue<int, std::vector<int>, bool(*)(int,int)> pq(my::ComIntLess); //函数名当做函数指针传过去 // pq.push(6); // pq.push(4); // pq.push(7); // pq.push(3); // pq.push(1); // pq.push(9); // while (!pq.empty()) // { // cout << pq.top() << " "; // pq.pop(); // } // cout << endl; // //} // // //int main() //{ // test_priority_queue(); // return 0; //} //仿函数版2测试 void test_priority_queue1() { //问题:优先级队列(priority_queue)默认大的优先级高,但传的是less仿函数<,底层是一个大堆 //如果想切换成小的优先级高,则传greater仿函数,底层是一个小堆, //这种设计是反过来的,设计有些违反常规 //my::priority_queue<int> pq; //默认是大堆 less比较< my::priority_queue<int, std::vector<int>, my::greater<int>> pq; //greater<int> 仿函数,默认小的优先级高,这里为小堆 pq.push(6); pq.push(4); pq.push(7); pq.push(3); pq.push(1); pq.push(9); while (!pq.empty()) { cout << pq.top() << " "; pq.pop(); } cout << endl; } void test_function1() { //std::vector<int> v; //v.push_back(3); //v.push_back(6); //v.push_back(9); //v.push_back(1); //v.push_back(5); //v.push_back(2); //for (auto e : v) //{ // cout << e << " "; //} //cout << endl; //std::sort(v.begin(), v.end()); //默认升序,但调用less仿函数,与priority_queue 的仿函数顺序不一样 //for (auto e : v) //{ // cout << e << " "; //} //cout << endl; //std::sort(v.begin(), v.end(),greater<int>()); //降序,但调用greater仿函数,与priority_queue 的仿函数顺序不一样 //for (auto e : v) //这里greater传的是匿名对象 //{ // cout << e << " "; //} //cout << endl; //给数组排序 //指向数组的原生指针,本身就是天然的迭代器 int a[6] = { 2,7,5,9,6,3 }; for (auto e : a) { cout << e << " "; } cout << endl; std::sort(a, a + 6); //默认升序 for (auto e : a) { cout << e << " "; } cout << endl; std::sort(a, a + 6, greater<int>()); //降序,这里greater传的是匿名对象, for (auto e : a) { cout << e << " "; } cout << endl; } //struct Goods //{ // /*bool operator<(const Goods& g)const // { // return _price < g._price; // }*/ // // 多种方式比较,运算符重载就不适用,可以使用仿函数 // // string _name; // double _price; // size_t _saleNum; // //}; 输入输出流运算符重载 //std::ostream& operator<<(std::ostream& out, const Goods& g) //{ // out << g._name <<" " << g._price <<" " << g._saleNum << endl; // return out; //} //std::istream& operator>>(std::istream& in, Goods& g) //{ // in>> g._name >> g._price >> g._saleNum; // return in; //} //struct LessPrice //{ // bool operator()(const Goods& g1,const Goods& g2)const // { // return g1._price < g2._price; // } // //}; //struct GreaterPrice //{ // bool operator()(const Goods& g1, const Goods& g2)const // { // return g1._price > g2._price; // } //}; // //struct LessSaleNum //{ // bool operator()(const Goods& g1, const Goods& g2)const // { // return g1._saleNum <g2._saleNum; // } //}; //struct GreaterSaleNum //{ // bool operator()(const Goods& g1, const Goods& g2)const // { // return g1._saleNum > g2._saleNum; // } //}; // //void test_function2() //{ // Goods gds[] = { { "苹果", 2.1 ,100}, { "香蕉", 3 ,211}, { "橙子", 2.2,200 }, {"菠萝", 1.5,190} }; // sort(gds, gds + sizeof(gds) / sizeof(gds[0]),LessPrice()); // for (auto e : gds) // { // cout << e; // } // cout << endl; // sort(gds, gds + sizeof(gds) / sizeof(gds[0]), GreaterPrice()); // for (auto e : gds) // { // cout << e; // } // cout << endl; // sort(gds, gds + sizeof(gds) / sizeof(gds[0]), LessSaleNum()); // for (auto e : gds) // { // cout << e; // } // cout << endl; // sort(gds, gds + sizeof(gds) / sizeof(gds[0]),GreaterSaleNum()); // for (auto e : gds) // { // cout << e ; // } // cout << endl; //} //建堆测试 void test_priority_queue2() { int a[] = { 2,7,5,9,8,2,1 }; //my::priority_queue<int> pq(a, a + 7); my::priority_queue<int, std::vector<int>, my::greater<int>> pq(a, a + 7); cout << pq.top()<<endl; } int main() { //test_priority_queue1(); //test_function1(); //test_function2(); test_priority_queue2(); return 0; }
4.反向迭代器 :
与正向迭代器相比,除了++、--时方向相反,其他操作基本一致
扩展:迭代器萃取技术。
对于反向迭代器的模拟实现其实涉及到许多综合性实现,比如模板(只传模板参数、传多个参数),传不同参数实现用到的技术也不一样,而对于STL标准库里的实现则涉及到迭代器的萃取,这里只做简单学习了解,具体可参见STL源码。
以下则模拟实现了模板(只传模板参数、传多个参数)两个版本,但实际应用中,建议使用传多个参数。
4.1 ReverseIterator.h:
#pragma once //显示传3个参数 namespace my { template<class Iterator,class Ref,class Ptr> struct Reverse_iterator { Iterator _it; typedef Reverse_iterator<Iterator, Ref, Ptr>Self; Reverse_iterator(Iterator it) :_it(it) {} Ref operator*() { Iterator tmp = _it; return *(--tmp); } Ptr operator->() { return &(operator*()); } Self& operator++() { --_it; return *this; } Self& operator--() { ++_it; return *this; } bool operator!=(const Self& s) { return _it != s._it; } }; } 只传迭代器 //namespace my //{ // template<class Iterator> // struct Reverse_iterator // { // Iterator _it; // typedef Reverse_iterator<Iterator>Self; // //萃取 // typedef typename Iterator::reference reference; // typedef typename Iterator::pointer pointer; // Reverse_iterator(Iterator it) // :_it(it) // {} // //类模板、模板虚拟类型 在没有实例化之前不能去它里面找内嵌定义的类型 // //否则,类模板没有实例化,找出来的也是虚拟类型,后期无法处理 // //typename会告诉编译器后面这一块是一个类型,等Iterator实例化以后,再去它里面找这个内嵌类型 // //非萃取写法 // /*typename Iterator::reference operator*() // { // Iterator tmp = _it; // return *(--tmp); // } // // typename Iterator::pointer operator->() // { // return &(operator*()); // }*/ // //萃取写法: // reference operator*() // { // Iterator tmp = _it; // return *(--tmp); // } // // pointer operator->() // { // return &(operator*()); // } // // Self& operator++() // { // --_it; // return *this; // } // Self& operator--() // { // ++_it; // return *this; // } // bool operator!=(const Self& s) // { // return _it != s._it; // } // }; //}
4.2 list的反向迭代器:
//反向迭代器传3个参数 #pragma once #include<iostream> #include<list> #include<cassert> #include"ReverseIterator.h" using namespace std; //自定义命名空间,防止与库里的冲突 namespace my { template<class T> struct list_node { list_node<T>* _next; list_node<T>* _prev; T _data; list_node(const T& val) //或A:给个缺省值list_node(const T& val=T()) :_next(nullptr) , _prev(nullptr) , _data(val) {} }; template<class T, class Ref, class Ptr> //多个模板参数 struct __list_iterator { typedef list_node<T> Node; typedef __list_iterator<T, Ref, Ptr> self; Node* _node; __list_iterator(Node* node) :_node(node) {} Ref operator*() { return _node->_data; } self& operator++() //默认为前置++ { _node = _node->_next; return *this; } self& operator++(int) //后置++ { self tmp(*this); _node = _node->_next; return tmp; } self& operator--() //前置-- { _node = _node->_prev; return *this; } self& operator--(int) //后置-- { self tmp(*this); _node = _node->_prev; return tmp; } bool operator!=(const self& it) { return _node != it._node; } bool operator==(const self& it) { return _node == it._node; } //"->"重载 Ptr operator->() { return &(operator*());//等价于return &_node->_data; } }; template<class T> class list { typedef list_node<T> Node; public: typedef __list_iterator<T, T&, T*> iterator; typedef __list_iterator<T, const T&, const T*> const_iterator; //反向迭代器适配支持 typedef Reverse_iterator<iterator, T&, T*>reverse_iterator; typedef Reverse_iterator<const_iterator, const T&, const T*>const_reverse_iterator; reverse_iterator rbegin() { return reverse_iterator(end()); } reverse_iterator rend() { return reverse_iterator(begin()); } const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } //迭代器 iterator begin() { return iterator(_head->_next); } iterator end() { return iterator(_head); } //const迭代器:多模板参数,附用普通迭代器 const_iterator begin() const { return const_iterator(_head->_next); } const_iterator end() const { return const_iterator(_head); } //构造函数 list() { _head = new Node(T()); //或A:_head = new Node(); A对应上面的A语句 _head->_next = _head; _head->_prev = _head; } //析构函数 ~list() { clear(); delete _head; _head = nullptr; } //lt2(lt1) //构造函数传统写法 //list(const list<T>& lt) //{ // _head = new Node(T()); //或A:_head = new Node(); A对应上面的A语句 // _head->_next = _head; // _head->_prev = _head; // for (auto e : lt) // { // push_back(e); // } //} //初始化 void empty_init() { _head = new Node(T()); //或A:_head = new Node(); A对应上面的A语句 _head->_next = _head; _head->_prev = _head; } template <class InputIterator> list(InputIterator first, InputIterator last) { empty_init(); while (first != last) { push_back(*first); ++first; } } //交换 void swap(list<T>& lt) { std::swap(_head, lt._head); } //构造函数——现代写法 list(const list<T>& lt) { empty_init(); list<T> tmp(lt.begin(), lt.end()); swap(tmp); } //赋值重载——现代写法 list<T>& operator=(list<T> lt) { swap(lt); return *this; } void clear() //clear清理数据,结构还在 { iterator it = begin(); while (it != end()) { it = erase(it); } } //尾插 void push_back(const T& x) { /*Node* tail = _head->_prev; Node* newnode = new Node(x); tail->_next = newnode; newnode->_prev = tail; newnode->_next = _head; _head->_prev = newnode;*/ //附用insert insert(end(), x); } //头插 void push_front(const T& x) { insert(begin(), x); } //insert插入在pos位置之前 iterator insert(iterator pos, const T& x) { Node* newNode = new Node(x); Node* cur = pos._node; Node* prev = cur->_prev; prev->_next = newNode; newNode->_prev = prev; newNode->_next = cur; cur->_prev = newNode; return iterator(newNode); } //尾删 void pop_back() { erase(--end()); } //头删 void pop_front() { erase(begin()); } //删除 iterator erase(iterator pos) { assert(pos != end()); Node* cur = pos._node; Node* prev = cur->_prev; Node* next = cur->_next; prev->_next = next; next->_prev = prev; delete cur; return iterator(next); } //总结:list::insert不存在迭代器失效问题 //list::erase存在野指针导致的迭代器失效 private: Node* _head; }; } //反向迭代器 //与正向迭代器相比,除了++、--时方向相反,其他操作基本一致 只传迭代器(list只传迭代器,勉强能实现运行,但vector只传迭代器就比较复杂) //#pragma once //#include<iostream> //#include<list> //#include<cassert> //#include"ReverseIterator.h" //using namespace std; // 自定义命名空间,防止与库里的冲突 //namespace my //{ // template<class T> // struct list_node // { // list_node<T>* _next; // list_node<T>* _prev; // T _data; // // list_node(const T& val) //或A:给个缺省值list_node(const T& val=T()) // :_next(nullptr) // , _prev(nullptr) // , _data(val) // {} // }; // template<class T, class Ref, class Ptr> //多个模板参数 // struct __list_iterator // { // typedef list_node<T> Node; // typedef __list_iterator<T, Ref, Ptr> self; // typedef Ref reference; // typedef Ptr pointer; // Node* _node; // __list_iterator(Node* node) // :_node(node) // {} // Ref operator*() // { // return _node->_data; // } // self& operator++() //默认为前置++ // { // _node = _node->_next; // return *this; // } // self& operator++(int) //后置++ // { // self tmp(*this); // _node = _node->_next; // return tmp; // } // self& operator--() //前置-- // { // _node = _node->_prev; // return *this; // } // self& operator--(int) //后置-- // { // self tmp(*this); // _node = _node->_prev; // return tmp; // } // bool operator!=(const self& it) // { // return _node != it._node; // } // bool operator==(const self& it) // { // return _node == it._node; // } // //"->"重载 // Ptr operator->() // { // return &(operator*());//等价于return &_node->_data; // } // // }; // // // template<class T> // class list // { // typedef list_node<T> Node; // public: // typedef __list_iterator<T, T&, T*> iterator; // typedef __list_iterator<T, const T&, const T*> const_iterator; // // //反向迭代器适配支持 // typedef Reverse_iterator<iterator>reverse_iterator; // typedef Reverse_iterator<const_iterator >const_reverse_iterator; // // reverse_iterator rbegin() // { // return reverse_iterator(end()); // } // reverse_iterator rend() // { // return reverse_iterator(begin()); // } // const_reverse_iterator rbegin() const // { // return const_reverse_iterator(end()); // } // const_reverse_iterator rend() const // { // return const_reverse_iterator(begin()); // } // // //迭代器 // iterator begin() // { // return iterator(_head->_next); // } // iterator end() // { // return iterator(_head); // } // //const迭代器:多模板参数,附用普通迭代器 // const_iterator begin() const // { // return const_iterator(_head->_next); // } // const_iterator end() const // { // return const_iterator(_head); // } // // //构造函数 // list() // { // _head = new Node(T()); //或A:_head = new Node(); A对应上面的A语句 // // _head->_next = _head; // _head->_prev = _head; // } // //析构函数 // ~list() // { // clear(); // delete _head; // _head = nullptr; // } // //lt2(lt1) // //构造函数传统写法 // //list(const list<T>& lt) // //{ // // _head = new Node(T()); //或A:_head = new Node(); A对应上面的A语句 // // _head->_next = _head; // // _head->_prev = _head; // // for (auto e : lt) // // { // // push_back(e); // // } // //} // //初始化 // void empty_init() // { // _head = new Node(T()); //或A:_head = new Node(); A对应上面的A语句 // _head->_next = _head; // _head->_prev = _head; // } // // template <class InputIterator> // list(InputIterator first, InputIterator last) // { // empty_init(); // while (first != last) // { // push_back(*first); // ++first; // } // } // //交换 // void swap(list<T>& lt) // { // std::swap(_head, lt._head); // } // //构造函数——现代写法 // list(const list<T>& lt) // { // empty_init(); // list<T> tmp(lt.begin(), lt.end()); // swap(tmp); // } // //赋值重载——现代写法 // list<T>& operator=(list<T> lt) // { // swap(lt); // return *this; // } // void clear() //clear清理数据,结构还在 // { // iterator it = begin(); // while (it != end()) // { // it = erase(it); // } // } // //尾插 // void push_back(const T& x) // { // /*Node* tail = _head->_prev; // Node* newnode = new Node(x); // // tail->_next = newnode; // newnode->_prev = tail; // newnode->_next = _head; // _head->_prev = newnode;*/ // //附用insert // insert(end(), x); // } // //头插 // void push_front(const T& x) // { // insert(begin(), x); // } // //insert插入在pos位置之前 // iterator insert(iterator pos, const T& x) // { // Node* newNode = new Node(x); // Node* cur = pos._node; // Node* prev = cur->_prev; // prev->_next = newNode; // newNode->_prev = prev; // newNode->_next = cur; // cur->_prev = newNode; // return iterator(newNode); // } // //尾删 // void pop_back() // { // erase(--end()); // } // //头删 // void pop_front() // { // erase(begin()); // } // //删除 // iterator erase(iterator pos) // { // assert(pos != end()); // Node* cur = pos._node; // Node* prev = cur->_prev; // Node* next = cur->_next; // prev->_next = next; // next->_prev = prev; // delete cur; // return iterator(next); // } // //总结:list::insert不存在迭代器失效问题 // //list::erase存在野指针导致的迭代器失效 // private: // Node* _head; // }; // //} // // 反向迭代器 与正向迭代器相比,除了++、--时方向相反,其他操作基本一致
4.3 vector的反向迭代器:
//反向迭代器传3个参数 #pragma once //模拟实现vector #include<iostream> #include<string> #include<vector> #include<cassert> #include"ReverseIterator.h" using namespace std; //自定义命名空间,防止与库里的冲突 namespace my { template<class T> class vector { public: typedef T* iterator; typedef const T* const_iterator; //反向迭代器适配支持 typedef Reverse_iterator<iterator, T&, T*>reverse_iterator; typedef Reverse_iterator<const_iterator, const T&, const T*>const_reverse_iterator; reverse_iterator rbegin() { return reverse_iterator(end()); } reverse_iterator rend() { return reverse_iterator(begin()); } const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } //构造函数 vector() :_start(nullptr) , _finish(nullptr) , _endofstorage(nullptr) {} //使用n个val构造函数 vector(size_t n, const T& val = T()) :_start(nullptr) , _finish(nullptr) , _endofstorage(nullptr) { reserve(n); for (size_t i = 0; i < n; ++i) { push_back(val); } } vector(int n, const T& val = T()) :_start(nullptr) , _finish(nullptr) , _endofstorage(nullptr) { reserve(n); for (size_t i = 0; i < n; ++i) { push_back(val); } } //类模板,类构造 template<class InputIterator> vector(InputIterator first, InputIterator last) : _start(nullptr) , _finish(nullptr) , _endofstorage(nullptr) { while (first != last) { push_back(*first); ++first; } } void swap(vector<T>& v) { std::swap(_start, v._start); std::swap(_finish, v._finish); std::swap(_endofstorage, v._endofstorage); } //拷贝构造函数(使用现代写法) vector(const vector<T>& v) : _start(nullptr) , _finish(nullptr) , _endofstorage(nullptr) { vector<T> tmp(v.begin(), v.end()); swap(tmp); //this->swap(tmp); } //赋值重载函数(现代写法) vector<T>& operator=(vector<T> v) { swap(v); //this->swap(v); return *this; } //析构函数(资源管理) ~vector() { if (_start) { delete[] _start; _start = _finish = _endofstorage = nullptr; } } iterator begin() { return _start; } iterator end() { return _finish; } const_iterator begin() const { return _start; } const_iterator end() const { return _finish; } size_t size() const { return _finish - _start; } size_t capacity() const { return _endofstorage - _start; } void reserve(size_t n) { size_t sz = size(); if (n > capacity()) { T* tmp = new T[n]; if (_start) { //memcpy(tmp, _start, size() * sizeof(T)); //浅拷贝问题 for (size_t i = 0; i < size(); ++i) { tmp[i] = _start[i]; } delete[] _start; } _start = tmp; } _finish = _start + sz; _endofstorage = _start + n; } //总结:vector<T>中,当T涉及深拷贝的类型时,如:string、vector<T>等等, //扩容使用memcpy拷贝数据会存在浅拷贝问题,造成析构两次 //解决:使用传值拷贝,如上 void push_back(const T& x) { /*if (_finish == _endofstorage) { size_t newCapacity = capacity() == 0 ? 4 : capacity() * 2; reserve(newCapacity); } *_finish = x; ++_finish;*/ //附用insert insert(end(), x); } void pop_back() { /*if (_finish > _start) { --_finish; }*/ //附用erase erase(end() - 1); } T& operator[](size_t pos) { assert(pos < size()); return _start[pos]; } const T& operator[](size_t pos) const { assert(pos < size()); return _start[pos]; } //写在类里的小函数,被当做内联函数处理,减少了多次调用建立栈帧 //void resize(size_t n, const T& val = T()) void resize(size_t n, T val = T()) //T()匿名对象,调用默认构造函数,若T()为int(内置类型), { //C++对于内置类型也可以认为有构造函数、析构函数,才能支持模板,只是int为0,double为0.1 /*int i = 0; int j = int(); int k = int(1);*/ if (n > capacity()) { reserve(n); } if (n > size()) { while (_finish < _start + n) { *_finish = val; ++_finish; } } else { _finish = _start + n; } } iterator insert(iterator pos, const T& x) //返回值为iterator,解决迭代器失效问题 { //如果pos传引用,但有些时候,传不过去 //检查参数 assert(pos >= _start && pos <= _finish); //扩容 //扩容以后,pos就失效了,要更新 //insert导致的迭代器失效,是因为pos没更新 if (_finish == _endofstorage) { size_t n = pos - _start; size_t newCapacity = capacity() == 0 ? 4 : capacity() * 2; reserve(newCapacity); pos = _start + n; } //挪动数据 iterator end = _finish - 1; while (end >= pos) { *(end + 1) = *end; --end; } *pos = x; ++_finish; return pos; } //总结:迭代器在insert里的两种失效: //1.pos失效 2.迭代器it失效 iterator erase(iterator pos) { assert(pos >= _start && pos <= _finish); iterator it = pos + 1; while (it != _finish) { *(it - 1) = *it; ++it; } --_finish; return pos; } //总结: //1.erase的失效都是意义变了,过着不在有效访问数据有效范围 //2.一般不会使用缩容的方案,那么erase的失效也不存在野指针的失效 //在VS和Linux不同环境下,处理不同 //erase(pos),使得pos失效,pos的意义改变,但是不同环境平台的处理不一样 //在使用的时候,统一以失效的角度看待 //整体总结: //对于insert和erase造成的迭代器失效问题,Linux环境下g++检查不严格,基本依靠操作系统自身野指针越界检查机制 //Windows环境下,VS系列检查严格,使用一些强制检查机制,意义改变造成的失效,也可能会检查出来 //vector迭代器的失效有两种: //1.扩容、缩容,导致形成野指针失效 //2.迭代器指向的位置意义改变 //这些通过操作系统的越界检查机制不一定能检查到 //而通过编译器实现机制检查,相对靠谱 void clear() { _finish = _start; } private: iterator _start; iterator _finish; iterator _endofstorage; }; } 只传迭代器(vector只传迭代器,需要萃取或者将T*封装,这里未实现) //#pragma once 模拟实现vector //#include<iostream> //#include<string> //#include<vector> //#include<cassert> //#include"ReverseIterator.h" //using namespace std; // 自定义命名空间,防止与库里的冲突 //namespace my //{ // template<class T> // class vector // { // public: // typedef T* iterator; // typedef const T* const_iterator; // //反向迭代器适配支持 // typedef Reverse_iterator<iterator, T&, T*>reverse_iterator; // typedef Reverse_iterator<const_iterator, const T&, const T*>const_reverse_iterator; // // 只传迭代器需要支持萃取或者将T*封装 // //typedef Reverse_iterator<iterator>reverse_iterator; // //typedef Reverse_iterator<const_iterator>const_reverse_iterator; // // reverse_iterator rbegin() // { // return reverse_iterator(end()); // } // reverse_iterator rend() // { // return reverse_iterator(begin()); // } // const_reverse_iterator rbegin() const // { // return const_reverse_iterator(end()); // } // const_reverse_iterator rend() const // { // return const_reverse_iterator(begin()); // } // // //构造函数 // vector() // :_start(nullptr) // , _finish(nullptr) // , _endofstorage(nullptr) // {} // //使用n个val构造函数 // vector(size_t n, const T& val = T()) // :_start(nullptr) // , _finish(nullptr) // , _endofstorage(nullptr) // { // reserve(n); // for (size_t i = 0; i < n; ++i) // { // push_back(val); // } // } // vector(int n, const T& val = T()) // :_start(nullptr) // , _finish(nullptr) // , _endofstorage(nullptr) // { // reserve(n); // for (size_t i = 0; i < n; ++i) // { // push_back(val); // } // } // //类模板,类构造 // template<class InputIterator> // vector(InputIterator first, InputIterator last) // : _start(nullptr) // , _finish(nullptr) // , _endofstorage(nullptr) // { // while (first != last) // { // push_back(*first); // ++first; // } // } // void swap(vector<T>& v) // { // std::swap(_start, v._start); // std::swap(_finish, v._finish); // std::swap(_endofstorage, v._endofstorage); // // } // //拷贝构造函数(使用现代写法) // vector(const vector<T>& v) // : _start(nullptr) // , _finish(nullptr) // , _endofstorage(nullptr) // { // vector<T> tmp(v.begin(), v.end()); // swap(tmp); //this->swap(tmp); // } // //赋值重载函数(现代写法) // vector<T>& operator=(vector<T> v) // { // swap(v); //this->swap(v); // return *this; // } // //析构函数(资源管理) // ~vector() // { // if (_start) // { // delete[] _start; // _start = _finish = _endofstorage = nullptr; // } // } // // iterator begin() // { // return _start; // } // iterator end() // { // return _finish; // } // const_iterator begin() const // { // return _start; // } // const_iterator end() const // { // return _finish; // } // size_t size() const // { // return _finish - _start; // } // size_t capacity() const // { // return _endofstorage - _start; // } // void reserve(size_t n) // { // size_t sz = size(); // if (n > capacity()) // { // T* tmp = new T[n]; // if (_start) // { // //memcpy(tmp, _start, size() * sizeof(T)); //浅拷贝问题 // for (size_t i = 0; i < size(); ++i) // { // tmp[i] = _start[i]; // } // delete[] _start; // } // _start = tmp; // } // _finish = _start + sz; // _endofstorage = _start + n; // } // //总结:vector<T>中,当T涉及深拷贝的类型时,如:string、vector<T>等等, // //扩容使用memcpy拷贝数据会存在浅拷贝问题,造成析构两次 // //解决:使用传值拷贝,如上 // void push_back(const T& x) // { // /*if (_finish == _endofstorage) // { // size_t newCapacity = capacity() == 0 ? 4 : capacity() * 2; // reserve(newCapacity); // } // *_finish = x; // ++_finish;*/ // // //附用insert // insert(end(), x); // } // void pop_back() // { // /*if (_finish > _start) // { // --_finish; // }*/ // // //附用erase // erase(end() - 1); // } // T& operator[](size_t pos) // { // assert(pos < size()); // return _start[pos]; // } // const T& operator[](size_t pos) const // { // assert(pos < size()); // return _start[pos]; // } // //写在类里的小函数,被当做内联函数处理,减少了多次调用建立栈帧 // //void resize(size_t n, const T& val = T()) // void resize(size_t n, T val = T()) //T()匿名对象,调用默认构造函数,若T()为int(内置类型), // { //C++对于内置类型也可以认为有构造函数、析构函数,才能支持模板,只是int为0,double为0.1 // /*int i = 0; // int j = int(); // int k = int(1);*/ // // if (n > capacity()) // { // reserve(n); // } // if (n > size()) // { // while (_finish < _start + n) // { // *_finish = val; // ++_finish; // } // } // else // { // _finish = _start + n; // } // } // iterator insert(iterator pos, const T& x) //返回值为iterator,解决迭代器失效问题 // { // //如果pos传引用,但有些时候,传不过去 // //检查参数 // assert(pos >= _start && pos <= _finish); // //扩容 // //扩容以后,pos就失效了,要更新 // //insert导致的迭代器失效,是因为pos没更新 // if (_finish == _endofstorage) // { // size_t n = pos - _start; // size_t newCapacity = capacity() == 0 ? 4 : capacity() * 2; // reserve(newCapacity); // pos = _start + n; // } // //挪动数据 // iterator end = _finish - 1; // while (end >= pos) // { // *(end + 1) = *end; // --end; // } // *pos = x; // ++_finish; // return pos; // } // //总结:迭代器在insert里的两种失效: // //1.pos失效 2.迭代器it失效 // // iterator erase(iterator pos) // { // assert(pos >= _start && pos <= _finish); // iterator it = pos + 1; // while (it != _finish) // { // *(it - 1) = *it; // ++it; // } // --_finish; // return pos; // } // //总结: // //1.erase的失效都是意义变了,过着不在有效访问数据有效范围 // //2.一般不会使用缩容的方案,那么erase的失效也不存在野指针的失效 // //在VS和Linux不同环境下,处理不同 // //erase(pos),使得pos失效,pos的意义改变,但是不同环境平台的处理不一样 // //在使用的时候,统一以失效的角度看待 // // //整体总结: // //对于insert和erase造成的迭代器失效问题,Linux环境下g++检查不严格,基本依靠操作系统自身野指针越界检查机制 // //Windows环境下,VS系列检查严格,使用一些强制检查机制,意义改变造成的失效,也可能会检查出来 // // //vector迭代器的失效有两种: // //1.扩容、缩容,导致形成野指针失效 // //2.迭代器指向的位置意义改变 // //这些通过操作系统的越界检查机制不一定能检查到 // //而通过编译器实现机制检查,相对靠谱 // void clear() // { // _finish = _start; // } // // private: // iterator _start; // iterator _finish; // iterator _endofstorage; // // }; //}
4.4 test.cpp:
#include"listplus.h" #include"vectorplus.h" #include<string> void test_list_r_iterator() { my::list<int> lt; lt.push_back(10); lt.push_back(20); lt.push_back(30); lt.push_back(40); lt.push_back(50); for (auto e : lt) { cout << e << " "; } cout << endl; my::list<int>::reverse_iterator rit = lt.rbegin(); while (rit != lt.rend()) { cout << *rit << " "; ++rit; } cout << endl; } void test_vector_r_iterator() { my::vector<int> v; v.push_back(1); v.push_back(2); v.push_back(3); v.push_back(4); v.push_back(5); for (auto e : v) { cout << e << " "; } cout << endl; my::vector<int>::reverse_iterator rit = v.rbegin(); while (rit != v.rend()) { cout << *rit << " "; ++rit; } cout << endl; } template<class T> void print_list(const my::list<T>& lt) { typename my::list<T>::const_iterator cit = lt.begin(); //auto cit = lt.begin(); //或直接使用auto while (cit != lt.end()) { cout << *cit << " "; ++cit; } cout << endl; } template<class Container> void print_Container(const Container& lt) { typename Container::const_iterator cit = lt.begin(); //auto cit = lt.begin(); //或直接使用auto while (cit != lt.end()) { cout << *cit << " "; ++cit; } cout << endl; } int main() { //test_list_r_iterator(); //test_vector_r_iterator(); my::list<int> lt1; lt1.push_back(1); lt1.push_back(2); lt1.push_back(3); lt1.push_back(4); print_list(lt1); print_Container(lt1); my::list<string> lt2; lt2.push_back("hello"); lt2.push_back("world"); print_list(lt2); print_Container(lt2); return 0; }
后记:
●由于作者水平有限,文章难免存在谬误之处,敬请读者斧正,俚语成篇,恳望指教!
——By 作者:新晓·故知