GeezerVison is showing github.com — Upload note code of chapter 3 iterator · github20210708/STLSourceCodeNote@5e74915
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboard +35Lines changed: 35 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +#include <vector> | | 2 | +#include <list> | | 3 | +#include <deque> | | 4 | +#include <algorithm> | | 5 | +#include <iostream> | | 6 | +using namespace std; | | 7 | + | | 8 | +// 迭代器是㆒种行为类似指针的对象,对operator*和operator->进行重载 | | 9 | + | | 10 | +int main() { | | 11 | + const int arraySize = 7; | | 12 | + int ia[arraySize] = {0, 1, 2, 3, 4, 5, 6}; | | 13 | + | | 14 | + vector<int> ivect(ia, ia + arraySize); | | 15 | + list<int> ilist(ia, ia + arraySize); | | 16 | + deque<int> ideque(ia, ia + arraySize); | | 17 | + | | 18 | + vector<int>::iterator it1 = find(ivect.begin(), ivect.end(), 4); | | 19 | + if (it1!=ivect.end()) | | 20 | + cout << "4 not found." << endl; | | 21 | + else | | 22 | + cout << "4 found. " << *it1 << endl; | | 23 | + | | 24 | + list<int>::iterator it2 = find(ilist.begin(), ilist.end(), 6); | | 25 | + if (it2!=ilist.end()) | | 26 | + cout << "6 not found." << endl; | | 27 | + else | | 28 | + cout << "6 found. " << *it2 << endl; | | 29 | + | | 30 | + deque<int>::iterator it3 = find(ideque.begin(), ideque.end(), 8); | | 31 | + if (it3!=ideque.end()) | | 32 | + cout << "8 not found." << endl; | | 33 | + else | | 34 | + cout << "8 found. " << *it3 << endl; | | 35 | +} |
Collapse file Copy file name to clipboard +15Lines changed: 15 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +template <class InputIterator, class T> | | 2 | +InputIterator find(InputIterator first, InputIterator last, const T& value) { | | 3 | + // 修改*first!=value | | 4 | + while (first!=last && *first!=value) | | 5 | + // while (first!=last && (*first).value()!=value) | | 6 | + ++first; | | 7 | + return first; | | 8 | +} | | 9 | + | | 10 | +template <class InputIterator, class Function> | | 11 | +InputIterator for_each(InputIterator first, InputIterator last, Function f) { | | 12 | + for (; first != last; ++first) | | 13 | + f(*first); | | 14 | + return first; | | 15 | +} |
Collapse file Copy file name to clipboard +33Lines changed: 33 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +// file: 3autoptr.cpp | | 2 | + | | 3 | +template <class T> | | 4 | +class auto_ptr { | | 5 | +public: | | 6 | + explicit auto_ptr(T *p = 0) : pointee(p) {} | | 7 | + | | 8 | + template <class U> | | 9 | + auto_ptr(auto_ptr<U>& rhs): pointee(rhs.release()) {} | | 10 | + | | 11 | + ~auto_ptr() { | | 12 | + delete pointee; | | 13 | + } | | 14 | + | | 15 | + template <class U> | | 16 | + auto_ptr<T>& operator=(auto_ptr<U>& rhs) { | | 17 | + if (this != &rhs) | | 18 | + reset(rhs.release()); | | 19 | + return *this; | | 20 | + } | | 21 | + T& operator*() const { | | 22 | + return *pointee; | | 23 | + } | | 24 | + T* operator->() const { | | 25 | + return pointee; | | 26 | + } | | 27 | + T* get() const { | | 28 | + return pointee; | | 29 | + } | | 30 | + | | 31 | +private: | | 32 | + T *pointee; | | 33 | +}; |
Collapse file Copy file name to clipboard +46Lines changed: 46 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +// file: 3mylist-iter-test.cpp | | 2 | +#include "3_2_algorithm.h" | | 3 | +#include "3_2_mylist-iter.h" | | 4 | +#include "3_2_mylist.h" | | 5 | +using namespace std; | | 6 | + | | 7 | +//为了完成一个针对 List而设计的迭代器,我们无可避免曝露了太多 List细节: | | 8 | +// 在 main()为了制作 begin和 end两个迭代器,我们曝露了 ListItem; | | 9 | +// 在 ListIter class 为了达成 operator++的目的,我们曝露了 ListItem的操作函式 next()。 | | 10 | +// 如果不是为了迭代器,ListItem 原本应该完全隐藏起来不曝光的。 | | 11 | +// 换句话说,要设计出 ListIter,首先必须对 List 的细节有非常丰富的了解。 | | 12 | +// 既然这无可避免,干脆就把迭代器的开发工作交给 List的设计者好了, | | 13 | +// 如此一来所有细节反而得以封装起来不被使用者看到。 | | 14 | +// 这正是为什么每一种 STL 容器都提供有专属迭代器的缘故。 | | 15 | + | | 16 | +// 如果不写全局比较函数,则需要更改find函数判定 | | 17 | +template <typename T> bool operator!=(const ListItem<T>& item, T n) { | | 18 | + return item.value() != n; | | 19 | +} | | 20 | + | | 21 | +int main() { | | 22 | + List<int> mylist; | | 23 | + | | 24 | + | | 25 | + for (int i = 0; i < 5; ++i) { | | 26 | + mylist.insert_front(i); | | 27 | + mylist.insert_end(i + 2); | | 28 | + } | | 29 | + | | 30 | + mylist.display(); | | 31 | + | | 32 | + ListIter<ListItem<int>> begin(mylist.front()); | | 33 | + ListIter<ListItem<int>> end; | | 34 | + ListIter<ListItem<int>> iter; | | 35 | + iter = find(begin, end, 3); | | 36 | + if (iter == end) | | 37 | + cout << "not found" << endl; | | 38 | + else | | 39 | + cout << "found. " << iter->value() << endl; | | 40 | + | | 41 | + iter = find(begin, end, 7); | | 42 | + if (iter == end) | | 43 | + cout << "not found" << endl; | | 44 | + else | | 45 | + cout << "found. " << iter->value() << endl; | | 46 | +} |
Collapse file Copy file name to clipboard +43Lines changed: 43 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +// file: 3mylist-iter.h | | 2 | + | | 3 | +// #include "3_2_mylist.h" | | 4 | + | | 5 | +template <class Item> | | 6 | +struct ListIter { | | 7 | + Item *ptr; // 保持与容器的联系 | | 8 | + | | 9 | + // default ctor | | 10 | + ListIter(Item* p =0) : ptr(p) {} | | 11 | + | | 12 | + // 解引用 dereference | | 13 | + Item& operator*() const { | | 14 | + return *ptr; | | 15 | + } | | 16 | + | | 17 | + // member access | | 18 | + Item* operator->() const { | | 19 | + return ptr; | | 20 | + } | | 21 | + | | 22 | + // prefix increment, 返回对象 | | 23 | + ListIter& operator++() { | | 24 | + ptr = ptr->next(); | | 25 | + return *this; | | 26 | + } | | 27 | + | | 28 | + // postfix increment, 返回值(新对象) | | 29 | + // int为占位符,提示编译器这是后自增 | | 30 | + ListIter operator++(int) { | | 31 | + ListIter temp = *this; | | 32 | + ++*this; // 调用前面的前自增 | | 33 | + return temp; | | 34 | + } | | 35 | + | | 36 | + bool operator==(const ListIter& i) const { | | 37 | + return ptr == i.ptr; | | 38 | + } | | 39 | + | | 40 | + bool operator!=(const ListIter& i) const { | | 41 | + return ptr != i.ptr; | | 42 | + } | | 43 | +}; |
Collapse file Copy file name to clipboard +86Lines changed: 86 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +// file: 3mylist.h | | 2 | +#include <iostream> | | 3 | + | | 4 | +// 先声明 | | 5 | +template <typename T> | | 6 | +class ListItem; | | 7 | + | | 8 | +template <typename T> | | 9 | +class List { | | 10 | +// 定义public以供访问 | | 11 | +public: | | 12 | + void insert_front(T value); | | 13 | + void insert_end(T value); | | 14 | + void display(std::ostream &os = std::cout) const; | | 15 | + ListItem<T> * front() { | | 16 | + return _front; | | 17 | + } | | 18 | + List(); | | 19 | + | | 20 | +private: | | 21 | + ListItem<T> *_end; | | 22 | + ListItem<T> *_front; | | 23 | + long _size; | | 24 | +}; | | 25 | + | | 26 | +// 自己实现 | | 27 | +template <typename T> | | 28 | +List<T>::List() { | | 29 | + _size = 0; | | 30 | + _front = NULL; | | 31 | + _end = NULL; | | 32 | +} | | 33 | + | | 34 | +template <typename T> | | 35 | +void List<T>::insert_front(T value) { | | 36 | + ListItem<T>* temp = new ListItem<T>(value); | | 37 | + temp->set_next(_front); | | 38 | + _front = temp; | | 39 | + _size++; | | 40 | +} | | 41 | + | | 42 | +template <typename T> | | 43 | +void List<T>::insert_end(T value) { | | 44 | + ListItem<T>* temp = new ListItem<T>(value); | | 45 | + ListItem<T> *last = _front; | | 46 | + while (last->next() != _end) | | 47 | + last = last->next(); | | 48 | + last->set_next(temp); | | 49 | + _end = temp->next(); | | 50 | + _size++; | | 51 | +} | | 52 | + | | 53 | +// 声明写了默认参数后定义不能重写 | | 54 | +template <typename T> | | 55 | +void List<T>::display(std::ostream &os) const { | | 56 | + ListItem<T> *temp = _front; | | 57 | + while (temp!= _end) { | | 58 | + std::cout << temp->value() << " "; | | 59 | + temp = temp->next(); | | 60 | + } | | 61 | + std::cout << std::endl; | | 62 | +} | | 63 | + | | 64 | +template <typename T> | | 65 | +class ListItem { | | 66 | +public: | | 67 | + T value() const { | | 68 | + return _value; | | 69 | + } | | 70 | + | | 71 | + ListItem* next() const { | | 72 | + return _next; | | 73 | + } | | 74 | + | | 75 | + void set_next(ListItem* i) { | | 76 | + _next = i; | | 77 | + } | | 78 | + | | 79 | + ListItem(T value) : _value(value) { | | 80 | + _next = NULL; | | 81 | + } | | 82 | + | | 83 | +private: | | 84 | + T _value; | | 85 | + ListItem *_next; | | 86 | +}; |
|