STL is an important part of the C ++ standard library. It is not only a reusable component library, but also a software framework that contains algorithms and data structures, it is also a good example of C ++ generic programming. Many advanced C ++ technologies are used in STL. This topic describes heavy-load operators. For more information, see C ++
Primer "and" STL source code analysis ".
The overload operator is a function with a special name: The operator symbol to be defined is retained after the operator is retained. This is the definition in C ++ Primer. In STL, the overload operator is mainly used in two places: one is the iterator and the other is the algorithm. This article describes the application in the iterator and the application in the algorithm. In this series of blog posts, the iterator is the key to STL. The iterator is like a smart pointer to various container objects, which is just my understanding. Common actions of pointers include the unreferenced operator (*), arrow operator (->), auto-increment, and auto-subtraction. For containers, these operators must be reloaded to adapt to their own pointer behavior. To overload these operators, the iterator is duty-free. Let's take a look at the source code of STL and make some modifications to make it clearer.
// Node definition, two-way linked list <br/> template <class T> <br/> struct List_node {<br/> List_node * next; <br/> List_node * prev; <br/> T data; <br/>}; <br/> // linked list iterator <br/> template <class T, class Ref, class Ptr> <br/> class List_iterator <br/>{< br/> public: <br/> List_node <T> * node; <br/> void Incr () {node = node-> next ;}< br/> void Decr () {node = node-> prev ;}< br/> public: <br/> typedef T value_type; <br/> typedef Ptr pointer; <B R/> typedef Ref reference; <br/> typedef size_t size_type; <br/> typedef ptrdiff_t difference_type; <br/> typedef bidirectional_iterator_tag iterator_category; </p> <p> typedef List_iterator <T, T &, T *> iterator; // iterator <br/> typedef List_iterator <T, const T &, const T *> const_iterator; <br/> typedef List_iterator <T, Ref, Ptr> self; </p> <p> List_iterator (List_node <T> * x ): node (x) {}// receives the constructor of the linked List node, which works well <br/> List _ Iterator () {}< br/> reference operator * () const {return node-> data ;}// unreference overloading <br/> pointer operator-> () const {return & (operator * () ;}// reload the arrow <br/> self & operator ++ () {this-> Incr (); return * this ;} // pre-increment overload <br/> self operator ++ (int) {self tmp = * this; this-> Incr (); return tmp ;} // Add a reload later <br/> self & operator -- () {this-> Decr (); return * this ;} // minus heavy load <br/> self operator -- (int) {self tmp = * this; t His-> Decr (); return tmp;} // re-load <br/> bool operator = (const List_iterator & x) const {return node = x. node;} // equal and heavy load <br/> bool operator! = (Const List_iterator & x) const {return node! = X. node;} // unequal overload <br/> };
The code above demonstrates how these operators are overloaded. In fact, this is a two-way linked list iterator definition, with auto increment and auto increment. Further, how do I use the iterator defined above for the linked list? The definition of the linked list is given below, and only some functions of the STL linked list are obtained. A test case is also given. It has passed the test in VS2008.
# Include <iostream> <br/> using namespace std; </p> <p> // node definition, bidirectional linked list, copy the above Code. <br/> // The iterator of the linked list, copy the above Code </p> <p> // resource distributor <br/> class MyAlloc <br/>{< br/> }; <br/> // linked List definition <br/> template <class T, class Alloc = MyAlloc> <br/> class List {<br/> public: <br/> typedef List_node <T> list_node; // node type <br/> typedef list_node * list_type; // node pointer </p> <p> typedef T value_type; <br/> typedef value_type * pointer; <br/> ty Pedef const value_type * const_pointer; <br/> typedef value_type & reference; <br/> typedef const value_type & const_reference; <br/> typedef size_t size_type; <br/> typedef ptrdiff_t difference_type; </p> <p> typedef List_iterator <T, T &, T *> iterator; // iterator <br/> typedef List_iterator <T, const T &, const T *> const_iterator; <br/> public: <br/> List () {node = get_node (); node-> next = node; node-> prev = nod E;} // construct the sentinel node <br/> ~ List () {clear () ;}< br/> // The returned type must be iterator, but the actually returned node pointer. Why? The key is that List_iterator has a constructor that accepts node pointers <br/> iterator begin () {return node-> next ;}< br/> const_iterator begin () const {return node-> next ;}< br/> iterator end () {return node ;}< br/> const_iterator end () const {return node ;} <br/> bool empty () const {return node-> next = node;} <br/> reference front () {return * begin ();} <br/> const_reference front () const {return * begin () ;}< br/> reference back (){ Return * (-- end () ;}< br/> const_reference back () const {return * (-- end ());} <br/> void push_front (const T & x) {insert (begin (), x) ;}< br/> void push_back (const T & x) {insert (end (), x) ;}< br/> void pop_front () {erase (begin () ;}< br/> void pop_back () {iterator tmp = end (); erase (-- tmp) ;}< br/> // insert node <br/> void insert (iterator pos, const T & x) {<br/> list_type tmp = get_node (); <br/> tmp-> data = X; <br/> tmp-> next = pos. node; <br/> tmp-> prev = pos. node-> prev; <br/> (pos. node-> prev)-> next = tmp; <br/> pos. node-> prev = tmp; <br/>}< br/> // delete a node <br/> iterator erase (iterator pos) {<br/> list_type next_node = pos. node-> next; <br/> list_type prev_node = pos. node-> prev; <br/> prev_node-> next = next_node; <br/> next_node-> prev = prev_node; <br/> put_node (pos. node); <br/> return next_node; <br/>}< br/> // clear all Node <br/> void clear () {<br/> list_type cur = node-> next; <br/> while (cur! = Node) <br/>{< br/> list_type tmp = cur; <br/> cur = cur-> next; <br/> put_node (tmp ); <br/>}< br/> node-> next = node; <br/> node-> prev = node; <br/>}< br/> private: <br/> list_type node; <br/> list_type get_node () {return new list_node;} // allocate space <br/> void put_node (list_type p) {delete p; p = NULL;} // release space <br/>}; <br/> // test case <br/> int main () <br/>{< br/> List <int> l; <br/> l. push_back (1); <br/> l. push_back (2); <br/> cout <l. front () <''<l. back () <endl; // 1 2 <br/> l. push_front (3); <br/> l. push_front (4); <br/> cout <l. front () <''<l. back () <endl; // 4 2 <br/> l. pop_back (); <br/> l. pop_front (); <br/> cout <l. front () <''<l. back () <endl; // 3 1 <br/> cout <l. empty () <endl; // 0 <br/> l. clear (); <br/> cout <l. empty () <endl; // 1 <br/> return 0; <br/>}
The above two procedures have provided some functions of the linked list. At the same time, we can see the application of the iterator and the implementation of the heavy-load operators. After figuring out the above Code, it may be easier to look at the source code of STL. similar to that, the core structure is basically like this.
Reposted Source
Http://blog.csdn.net/wuzhekai1985