STL运用的C++技术(7)——代码整合
来源:互联网 发布:excel数据下拉递增 编辑:程序博客网 时间:2024/05/22 16:00
本文将6篇文章中出现的代码整合在一起,主要参考了HP的STL源码。通过这些代码,不仅可以看到这些C++技术在STL中的运用,同时也能大致了解STL的架构组织及实现方法。首先给出一个测试用例,所有代码都是自定义的,未用到STL。读者可以建立一个C++工程,把这些代码加进去,就可以运行起来。方便之处在于,读者可以修改这些代码,实现一些自己的功能,以加深对于STL的理解。
STL真正实现中,其实也就是对下述代码的扩展,定义更多的容器、算法、函数对象、迭代器等,至于具体实现的方法,仅仅是数据结构、算法自身上的差异,整体的实现步骤或者说是架构都是一样的。比如如果要实现deque,就需要定义deque的迭代器,deque的数据结构。又比如要实现排序算法,它与容器没有关系,它的形参是迭代器。因此实现起来根本不用考虑具体的容器。当然有些容器的排序算法需要特别实现,比如List的排序算法就是单独实现的。再比如要实现新的函数对象,没有问题,只需继承最基本的两个类,然后实现自定义的功能。
当然,本文没有介绍STL的另一个重要组成部分,那就是内存的分配机制。感兴趣的读者可以看一下《STL源码剖析》这本书,或者找份源码看一下。
#include "List.h" //自定义的链表#include "Algorithm.h" //自定义的算法#include "Functional.h" //自定义的函数对象#include <iostream>using namespace std;//测试程序 VS2008下测试通过int main(){List<int> l; //自定义的链表,STL链表的部分功能l.push_back(1); //链表功能测试l.push_back(2);//测试 萃取迭代器的类型功能MyAdvance(l.begin(), 1); //输出Random_access_iterator_tag//测试 萃取迭代器所指的数据类型Iterator_traits<int *>::value_type x = 5; //特化 Iterator_traits<const int*>::value_type y = 6; //特化 Iterator_traits<List<int>::iterator>::value_type z = 7; //list 容器 cout<<x<<' '<<y<<' '<<z<<endl; //输出5 6 7 //测试算法cout<<"before Iter_swap : "<<*(l.begin())<<' '<<*(++l.begin())<<endl; //输出1 2 Iter_swap(l.begin(),++l.begin()); //交换两个迭代器的元素 cout<<"after Iter_swap : "<<*(l.begin())<<' '<<*(++l.begin())<<endl; //输出2 1 l.push_front(3); l.push_front(4);l.push_front(5); l.push_front(6);//测试函数对象//链表中的元素为 6 5 4 3 1 2 int count1 = Count_if(l.begin(), l.end(), bind2nd(less_equal<int>(), 10)); //求容器中小于等于10的元素个数 int count2 = Count_if(l.begin(), l.end(), not1(bind2nd(less_equal<int>(), 10))); //求容器中不小于等于10的元素个数,正好是上面结果的取反 cout<<count1<<' '<<count2<<endl; //输出6 0 int count3 = 0, count4 = 0;Count_if(l.begin(), l.end(), bind2nd(greater_equal<int>(), 3), count3); //求容器中大于等于3的元素个数 Count_if(l.begin(), l.end(), not1(bind2nd(greater_equal<int>(), 3)), count4); //求容器中小于3的元素个数 cout<<count3<<' '<<count4<<endl; //输出4 2 l.clear();return 0;}
首先给出迭代器萃取剂的定义,代码如下。可以看到内嵌型别技术,模板特化技术,重载函数的精妙运用。
//Iterator_traits.h#pragma once //迭代器分类,大写已便于标准库区分struct Input_iterator_tag {}; struct Output_iterator_tag {}; struct Forward_iterator_tag : public Input_iterator_tag {}; struct Bidirectional_iterator_tag : public Forward_iterator_tag {}; struct Random_access_iterator_tag : public Bidirectional_iterator_tag {}; //萃取剂 template<class I> struct Iterator_traits{ typedef typename I::value_type value_type; typedef typename I::iterator_category iterator_category; //迭代器的类型 typedef typename I::difference_type difference_type;typedef typename I::pointer pointer;typedef typename I::reference reference;}; //特化 原生指针 template<class T> struct Iterator_traits<T*>{ typedef T value_type; typedef Random_access_iterator_tag iterator_category; typedef ptrdiff_t difference_type;typedef T* pointer;typedef T& reference;}; //特化 原生常指针 template<class T> struct Iterator_traits<const T*>{ typedef T value_type; typedef Random_access_iterator_tag iterator_category; typedef ptrdiff_t difference_type;typedef const T* pointer;typedef const T& reference;}; //萃取剂#define VALUE_TYPE(I) Iterator_traits<I>::value_type() #define ITERATOR_CATEGORY(I) Iterator_traits<I>::iterator_category() #define DIFFERENCE_TYPE(I) Iterator_traits<I>::difference_type() #define POINTER(I) Iterator_traits<I>::pointer() #define REFERENCE(I) Iterator_traits<I>::reference() //自定义的advance函数,与STL差不多 template <class InputIterator, class Distance> inline void MyAdvance(InputIterator &i, Distance n) { _MyAdvance(i, n, ITERATOR_CATEGORY(InputIterator)); //萃取迭代器的类型 } template <class InputIterator, class Distance> inline void _MyAdvance(InputIterator& i, Distance n, Input_iterator_tag) { while (n--) ++i; cout<<"InputIterator"<<endl; } template <class BidirectionalIterator, class Distance> inline void _MyAdvance(BidirectionalIterator& i, Distance n, Bidirectional_iterator_tag) { if (n >= 0) while (n--) ++i; else while (n++) --i; cout<<"BidirectionalIterator"<<endl; } template <class RandomAccessIterator, class Distance> inline void _MyAdvance(RandomAccessIterator& i, Distance n, Random_access_iterator_tag) { i += n; cout<<"RandomAccessIterator"<<endl; }再给出一个容器的定义,这里用的List,实现了STL的部分功能,同时还出了相应的迭代器的实现。可以看到大量的重载操作符的实现。
//List_iterator.h#pragma once#include "Iterator_traits.h"//结点定义,双向链表 template <class T> struct List_node { List_node* next; List_node* prev; T data; }; //链表的迭代器 template<class T, class Ref, class Ptr> class List_iterator { public: List_node<T> *node; void Incr() { node = node->next; } void Decr() { node = node->prev; } public: typedef T value_type; typedef Ptr pointer; typedef Ref reference; typedef size_t size_type; typedef ptrdiff_t difference_type; typedef Bidirectional_iterator_tag iterator_category; //迭代器的类型是双向的 typedef List_iterator<T, T&, T*> iterator; //迭代器 typedef List_iterator<T, const T&, const T*> const_iterator; typedef List_iterator<T, Ref, Ptr> self; List_iterator(List_node<T>* x): node(x) {} //接受链表结点的构造函数,很管用 List_iterator() {} reference operator*() const { return node->data; } //解引用重载 pointer operator->() const { return &(operator*()); } //箭头重载 self& operator++() { this->Incr(); return *this; } //前增重载 self operator++(int) { self tmp = *this; this->Incr(); return tmp; } //后增重载 self& operator--() { this->Decr(); return *this; } //前减重载 self operator--(int) { self tmp = *this; this->Decr(); return tmp; } //后减重载 bool operator==(const List_iterator& x) const { return node == x.node; } //相等重载 bool operator!=(const List_iterator& x) const { return node != x.node; } //不相等重载 };
//List.h#pragma once #include "List_iterator.h"//资源分配器 class MyAlloc { }; //链表定义 template <class T, class Alloc = MyAlloc > class List { public: typedef List_node<T> list_node; //结点类型 typedef list_node* list_type; //结点指针 typedef T value_type; typedef value_type* pointer; typedef const value_type* const_pointer; typedef value_type& reference; typedef const value_type& const_reference; typedef size_t size_type; typedef ptrdiff_t difference_type; typedef List_iterator<T, T&, T*> iterator; //迭代器 typedef List_iterator<T, const T&, const T*> const_iterator; public: List() { node = get_node(); node->next = node; node->prev = node; } //构造哨兵结点 ~List() { clear(); } //返回类型要求是iterator,而实际返回的是结点指针,为什么可以呢?关键在于List_iterator有一个接受结点指针的构造函数 iterator begin() { return node->next; } const_iterator begin() const { return node->next; } iterator end() { return node; } const_iterator end() const { return node; } bool empty() const { return node->next == node; } reference front() { return *begin(); } const_reference front() const { return *begin(); } reference back() { return *(--end()); } const_reference back() const { return *(--end()); } void push_front(const T& x) { insert(begin(), x); } void push_back(const T& x) { insert(end(), x); } void pop_front() { erase(begin()); } void pop_back() { iterator tmp = end(); erase(--tmp); } //插入结点 void insert(iterator pos, const T &x) { list_type tmp = get_node(); tmp->data = x; tmp->next = pos.node; tmp->prev = pos.node->prev; (pos.node->prev)->next = tmp; pos.node->prev = tmp; } //删除结点 iterator erase(iterator pos) { list_type next_node = pos.node->next; list_type prev_node = pos.node->prev; prev_node->next = next_node; next_node->prev = prev_node; put_node(pos.node); return next_node; } //清除所有结点 void clear() { list_type cur = node->next; while(cur != node) { list_type tmp = cur; cur = cur->next; put_node(tmp); } node->next = node; node->prev = node; } private: list_type node; list_type get_node() { return new list_node; } //分配空间 void put_node(list_type p) { delete p; p = NULL; } //释放空间 };再来给出函数对象的定义,可以看到绑定器,取反器的具体实现。
//Functional.h#pragma once //用来定义一元操作的参数类别和返回值类别 template <class Arg, class Result> struct unary_function { typedef Arg argument_type; //内嵌型别技术 typedef Result result_type; }; //用来定义二元操作的参数类别和返回值类别 template <class Arg1, class Arg2, class Result> struct binary_function { typedef Arg1 first_argument_type; typedef Arg2 second_argument_type; typedef Result result_type; }; //一元操作,就两个 template <class T> struct negate : public unary_function<T, T> { T operator()(const T& x) const { return -x; } }; template <class T> struct logical_not : public unary_function<T,bool> { bool operator()(const T& x) const { return !x; } }; //加减乘除取模 template <class T> struct plus : public binary_function<T, T, T> { T operator()(const T& x, const T& y) const { return x + y; } }; template <class T> struct minus : public binary_function<T, T, T> { T operator()(const T& x, const T& y) const { return x - y; } }; template <class T> struct multiplies : public binary_function<T, T , T> { T operator()(const T& x, const T& y) const { return x * y; } }; template <class T> struct divides : public binary_function<T ,T, T> { T operator()(const T& x, const T& y) const { return x / y; } }; template <class T> struct modulus : public binary_function<T, T, T> { T operator()(const T& x, const T& y) const { return x % y; } }; //关系运算 template <class T> struct equal_to : public binary_function<T, T, bool> { bool operator()(const T& x, const T& y) const { return x == y; } }; template <class T> struct not_equal_to : public binary_function<T, T,bool> { bool operator()(const T& x, const T& y) const { return x != y; } }; template <class T> struct greater : public binary_function<T, T, bool> { bool operator()(const T& x, const T& y) const { return x > y; } }; template <class T> struct less : public binary_function<T, T, bool> { bool operator()(const T& x, const T& y) const { return x < y; } }; template <class T> struct greater_equal : public binary_function<T, T, bool> { bool operator()(const T& x, const T& y) const { return x >= y; } }; template <class T> struct less_equal : public binary_function<T, T, bool> { bool operator()(const T& x, const T& y) const { return x <= y; } }; //逻辑运算 template <class T> struct logical_and : public binary_function<T, T, bool>{ bool operator()(const T& x, const T& y) const { return x && y; } }; template <class T> struct logical_or : public binary_function<T, T, bool> { bool operator()(const T& x, const T& y) const { return x || y; } }; //绑定第一个参数 template <class Operation> class binder1st: public unary_function<typename Operation::second_argument_type, typename Operation::result_type> { public: binder1st(const Operation& x, const typename Operation::first_argument_type& y) : op(x), value(y) {} //构造函数 typename Operation::result_type operator()(const typename Operation::second_argument_type& x) const { return op(value, x); //固定第一个参数 } protected: Operation op; typename Operation::first_argument_type value; }; //绑定第二个参数 template <class Operation> class binder2nd: public unary_function<typename Operation::first_argument_type,typename Operation::result_type> { public: binder2nd(const Operation& x, const typename Operation::second_argument_type& y) : op(x), value(y) {} typename Operation::result_type operator()(const typename Operation::first_argument_type& x) const { return op(x, value); //固定第二个参数 } protected: Operation op; typename Operation::second_argument_type value; }; //外部接口 template <class Operation, class T> inline binder1st<Operation> bind1st(const Operation& fn, const T& x) { typedef typename Operation::first_argument_type Arg1_type; return binder1st<Operation>(fn,Arg1_type(x)); } //外部接口 template <class Operation, class T> inline binder2nd<Operation> bind2nd(const Operation& fn, const T& x) { typedef typename Operation::second_argument_type Arg2_type; return binder2nd<Operation>(fn, Arg2_type(x)); } //一元操作求反 template <class Predicate> class unary_negate: public unary_function<typename Predicate::argument_type, bool> { protected: Predicate pred; public: explicit unary_negate(const Predicate& x) : pred(x) {} bool operator()(const typename Predicate::argument_type& x) const { return !pred(x); } }; //二元操作求反 template <class Predicate> class binary_negate : public binary_function<typename Predicate::first_argument_type, typename Predicate::second_argument_type,bool> { protected: Predicate pred; public: explicit binary_negate(const Predicate& x) : pred(x) {} bool operator()(const typename Predicate::first_argument_type& x, const typename Predicate::second_argument_type& y) const { return !pred(x, y); } }; //外部接口 template <class Predicate> inline unary_negate<Predicate> not1(const Predicate& pred) { return unary_negate<Predicate>(pred); } //外部接口 template <class Predicate> inline binary_negate<Predicate> not2(const Predicate& pred) { return binary_negate<Predicate>(pred); }最后给出算法的定义。可以看到STL的精髓在于算法与容器的分开设计,通过迭代器将两者粘合在一起,实在是精妙之极。
//Algorithm.h#pragma once //交换两个迭代器所指的元素 template <class InputIterator1, class InputIterator2> inline void Iter_swap(InputIterator1 a, InputIterator2 b) { _Iter_swap(a, b, VALUE_TYPE(InputIterator1)); //VALUE_TYPE返回迭代器的值类型 } //真正的交换函数 template <class InputIterator1, class InputIterator2, class T> inline void _Iter_swap(InputIterator1 a, InputIterator2 b, T) { T tmp = *a; *a = *b; *b = tmp; }//条件计数template <class InputIterator, class Predicate, class Size> void Count_if(InputIterator first, InputIterator last, Predicate pred, Size& n) { for ( ; first != last; ++first) if (pred(*first)) ++n; } //条件计数,有返回值template <class InputIterator, class Predicate> typename Iterator_traits<InputIterator>::difference_type Count_if(InputIterator first, InputIterator last, Predicate pred) { typename Iterator_traits<InputIterator>::difference_type n = 0; for ( ; first != last; ++first) if (pred(*first)) ++n; return n; }
本人享有博客文章的版权,转载请标明出处 http://blog.csdn.net/wuzhekai1985
- STL运用的C++技术(7)——代码整合
- STL运用的C++技术(7)——代码整合 .
- STL运用的C++技术(7)——代码整合
- STL运用的C++技术(7)——代码整合
- STL运用的C++技术——后记
- STL运用的C++技术——后记
- STL运用的C++技术(1)——成员模板
- STL运用的C++技术(2)——模板特化
- STL运用的C++技术(3)——模板实参推断
- STL运用的C++技术(4)——重载函数
- STL运用的C++技术(5)——重载操作符
- STL运用的C++技术(6)——函数对象
- STL运用的C++技术(5)——重载操作符
- STL运用的C++技术(1)——成员模板 .
- STL运用的C++技术(2)——模板特化 .
- STL运用的C++技术(3)——模板实参推断 .
- STL运用的C++技术(4)——重载函数 .
- STL运用的C++技术(6)——函数对象 .
- 回文数字
- TI Cortex M3串口转以太网例程分析1-----概述
- java 用动态数组实现线性表
- h264 编解码有用资料 -360doc
- 通过java反射改变listview fastscroll图片
- STL运用的C++技术(7)——代码整合
- sed的使用
- spring job
- 今天的实训
- android-ListActivity与HashMap的简单使用
- The APR based Apache Tomcat Native library which allows optimal performance in production environmen
- 超图hypergraph
- find 的命令是强大, 要会用才好
- The APR based Apache Tomcat Native library which allows optimal performance in production environme