View the truth of the iterator

Source: Internet
Author: User

In the previous article, we have customized an iterator class line_iterator, but it is not universal. Now, with the help of templates, we can define a templated iterator. To continue the linear search idea, first rewrite the simplefind () function to the function template tfind (). The Code is as follows:

template<typename T>T* tFind(T* start, T* end, T val){    while(start != end && *start != val)        ++start;    return *start == val ? start : (T*)0;}

However, tfind () can only accept the built-in pointer type, and the universality is still limited. To extend the applicability of tfind (), rewrite tfind ():

template<typename Iterator, typename T>Iterator tFind(Iterator start, Iterator end, const T& val){    while(start != end && *start != val)        ++start;    return start != end ? start : (Iterator)0;}

In the tfind () function template, in addition to the data type T, we also introduce an iterator type. Of course, iterator supports T *, but its range is far wider than that of built-in pointers. In fact, as long as the iterator can support the operator called internally by tfind! =, Operator ++ and other operator methods. Didn't our custom line_iterator do this? (If you do not know line_iterator, we suggest you take a rough look at the previous article)

Now, a new requirement is raised: linear search for Data Structure objects in a single-chain table. We know that each node in a single-chain table is connected using the next pointer. Therefore, when you perform the ++ operation on the node pointer of a node in the linked list, you cannot simply add 1 to the pointer, but this-> next. How can this behavior be achieved? Operator Overloading is in line with our requirements.

However, we cannot build a pointer to node * type to overload operator ++, because doing so will change the semantics of operator ++, and C ++ will not allow you to do that. However, if we put operator ++ into a custom class and become a member function role, there is no special restriction. That is to say, we can overload the class member Operator ++. The class mentioned here is actually an iterator class.

Well, let's implement the above ideas. First, it is easy to implement a single-chain table. You only need to define the struct of the node and implement it in the linked list mode during I/O operations:

// list: roll_listtypedef struct Student{    int num;    char name[10];    bool check;    struct Student* next;}Student,*roll_list;

We define a student structure (student), which includes the student ID, name, and whether to sign in to the three data domains. In addition, there is a next pointer pointing to the next node of the single-linked list. At the same time, rename the student * type to roll_list, indicating the vertex list.

In the main function, the operation on the linked list is like this: (do not confuse the code placement order. I will give the complete sample code at the end of the article)

    int num;    char ch;    roll_list tmp = NULL;    while(cin>>num && num != 0)    {        Student* pStu = new Student;        pStu->num = num;cin.get(ch);        cin.getline(pStu->name,sizeof(pStu->name));        pStu->check = false;                pStu->next = tmp;        tmp = pStu;    }

The TMP in the vertex list is the header pointer. If no student exists, TMP = NULL. Headers are used for data input. In addition, it indicates that the input end is 0.

In this way, we have successfully built a single-chain table. As we mentioned above, it is certainly not possible to directly call tfind (TMP, null, n), because tfind () must perform the ++ operation on the pointer internally, the default pointer does not work here. Next, let's take a look at how the iterator turns the storm. In fact, if you are familiar with smart pointers, you will find that the idea of the iterator is too similar to that of smart pointers. They are both internal pointer encapsulation and then implement the necessary interfaces, the user mistakenly thinks that it is a built-in pointer. If you have read the design mode, you probably know that this is the proxy mode. Let's define this iterator:

// list_iteratortemplate<typename T>class list_iterator{    T* m_ptr;public:    list_iterator():m_ptr(NULL){}    list_iterator(T* ptr):m_ptr(ptr){}    T& operator*()const    {        return *m_ptr;    }    T* operator->()const    {        return m_ptr;    }    bool operator==(const list_iterator& rhs)    {        return m_ptr == rhs.m_ptr;    }    bool operator!=(const list_iterator& rhs)    {        return !(m_ptr == rhs.m_ptr);    }    list_iterator& operator++()    {        m_ptr = m_ptr->next;        return *this;    }    list_iterator operator++(int)    {        list_iterator tmp = *this;        m_ptr = m_ptr->next;        return tmp;    }};

The list_iterator is written as a template. As a result, it not only supports the student linked list in the example, but also supports any other linked list containing the next pointer, thus improving the code versatility. As mentioned above, list_iterator is the encapsulation of internal build pointer T * m_ptr. The external use of list_iterator is like using T *, because the operator method of list_iterator can make it completely false. Now consider the call of tfind:

tFind(list_iterator<Student>(tmp),list_iterator<Student>(), num)

Parameters passed to tfind () include two list_iterator <student> temporary objects and an int-type num. Operator called inside tfind! =, Operator ++ and other operations, list_iterator is fully competent, because we have defined operator ++ and other methods for it.

The following is the running result of the sample program:

8 Marx 10 Mary 12 Mickey 13 Tom 20 jirui 0 input a student number to search: 10 find student: Student ID: 00010 name: Mary attendance: not signed yet

The sample code is as follows:

/* Tfind. CPP * created: btwsmile * Date: 2011-12-18 * remarks: ** input8 Marx 10 Mary 12 Mickey 13 Tom 20 girI 0 */# include <iostream> # include <iomanip> using namespace STD; // list: roll_listtypedef struct student {int num; char name [10]; bool check; struct student * Next;} student, * roll_list; // operaotr = (student, INT) bool operator = (const student & LHS, int RHs) {return LHS. num = RHS;} bool Operator! = (Const student & LHS, int RHs) {return! (LHS. num = RHs);} // list_iteratortemplate <typename T> class list_iterator {T * m_ptr; public: list_iterator (): m_ptr (null) {} list_iterator (T * PTR ): m_ptr (PTR) {} T & operator * () const {return * m_ptr;} t * operator-> () const {return m_ptr ;} bool operator = (const list_iterator & RHs) {return m_ptr = RHS. m_ptr;} bool Operator! = (Const list_iterator & RHs) {return! (M_ptr = RHS. m_ptr);} list_iterator & operator ++ () {m_ptr = m_ptr-> next; return * This;} list_iterator operator ++ (INT) {list_iterator TMP = * this; m_ptr = m_ptr-> next; return TMP ;}; // function template: tfind/* template <typename T> T * tfind (T * Start, T * end, t Val) {While (start! = End & * start! = Val) ++ start; return * Start = Val? Start: (T *) 0;} */template <typename iterator, typename T> iterator tfind (iterator start, iterator end, const T & Val) {While (start! = End & * start! = Val) ++ start; return start! = End? Start: (iterator) 0 ;}// main functionint main () {int num; char ch; roll_list TMP = NULL; while (CIN> num & num! = 0) {student * pstu = new student; pstu-> num = num; cin. get (CH); cin. getline (pstu-> name, sizeof (pstu-> name); pstu-> check = false; pstu-> next = TMP; TMP = pstu ;} cout <"input a student number to search:"; CIN> num; list_iterator <student> T; If (t = tfind (list_iterator <student> (TMP ), list_iterator <student> (), num ))! = NULL) {cout <"find Student: \ n"; cout <"student ID:" <SETW (5) <setfill ('0 ') <t-> num <"\ t name:" <t-> name <"\ t attendance:" <(t-> check? "Checked in": "not checked in");} else cout <"No such student in roll list"; cout <Endl; System ("pause "); return 0 ;}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.