1. 程式人生 > >C++沉思錄 使用迭代器

C++沉思錄 使用迭代器

 (1)虛擬序列

//建立一個讀取常量值的輸入迭代器 輸入迭代器的基本操作++ * != == 
    class Constant_ierator
    {
        public:
            Constant_ierator(int k =0):n(k)
            {
            }
            int operator*()const
            {
                return n ;
            }
            Constant_ierator& operator++()
            {
                ++count;
                return *this;
            }
            Constant_ierator& operator++(int)
            {
                Constant_ierator it = *this;
                ++count;
                return *this;
            }
            //迭代器相等的判斷 當且僅當生成相同資料的值 並且這些值都相等的時候 才能判斷兩個迭代器相等
            friend int operator== (const Constant_ierator &p  ,const  Constant_ierator &q)
            {
                return p.count==q.count && p.n ==q.n;

            }
            friend int operator!= (const Constant_ierator &p  ,const  Constant_ierator &q)
            {
                return !(p==q);
            }
            friend  Constant_ierator operator+(const Constant_ierator& p, int n)
            {

                Constant_ierator r = p;
                r.count +=n;
                return r;
            }
            
            friend  Constant_ierator operator+(int n,const Constant_ierator& p)
            {

                return p+n;
            }

        private:
        int n;
        int count;


    };
    template<class In,class Out>
    Out copyy(In start, In end ,Out dest)
    {

        while(start != end)
        {
            *dest++ = *start++;
        }
        return dest;
    }

 測試:

int main(int argc, char const *argv[])
{

    int y[1000];
    Constant_ierator c(20);
    copyy(c,c+1000,y);
    cout<<"************"<<endl;
    for(int i =0;i<1000;i++)
    cout<<y[i]<<endl;
    system("pause");
    return 0;
}

(2)輸出迭代器

#include<iostream>
#include<string>
using namespace std;
template<class T>
class ostream_iterstor
{
    public:
    ostream_iterstor(ostream & os,const char* s):strm(&os),str(s){}
    ostream_iterstor& operator++()
    {
        return *this;
    }
    ostream_iterstor& operator*()
    {
        return *this;
    }
    ostream_iterstor& operator++(int)
    {
        return *this;
    }
    ostream_iterstor& operator=(const T &t)
    {
        *strm <<t<<str;
        return *this;
    }
    friend int operator==(const ostream_iterstor &p,const ostream_iterstor& q)
    {
        return p.strm == q.strm && p.str ==q.str;
    }
     friend int operator!=(const ostream_iterstor &p,const ostream_iterstor& q)
    {
        return !(p.strm == q.strm && p.str ==q.str);
    }

    private:
    ostream *strm;
    const char* str;
};

測試

int main(int argc, char const *argv[])
{

    int y[1000];
    Constant_ierator c(20);
    copyy(c,c+1000,y);
    cout<<"************"<<endl;
    for(int i =0;i<1000;i++)
    cout<<y[i]<<endl;
   
    ostream_iterstor<int> z(cout,"**********華麗的分割線*********\n");
    copyy(c,c+1000,z);
     system("pause");
    return 0;
}

(3)輸入迭代器

輸入流的迭代器。相比於輸出流迭代器,輸入流迭代器顯然更為複雜。

1. 首先,不同於Ostream_iterator,我們設計的Istream_iterator必須支援比較操作才能判斷是否到達了檔案尾部。

2. Istream_iterator必須可以進行嘗試性的讀取,因為需要判斷是否已經到達檔案尾部。(即判斷輸入是否有效)

接下來看看我們的策略。我們將設計成每個Istream_iterator物件將有一個只能容納一個元素的緩衝區和一個表明緩衝區是否已滿的標誌(full)。引入緩衝區已滿的標誌,使我們可以將每個輸入分隔開。想想每當讀入一個值時,我們便將full標記為1,表明緩衝區已滿。而operator++又使full恢復為0。如此一來的效果便是我們可以遍歷虛擬的輸入序列。

那麼我們何時遍歷結束了?顯然是當我們不再輸入元素。當我們不再輸入元素時,我們往往會按下回車鍵。所以又可以說當我們讀入一個壞值便是輸入序列的結束。如此一來,

便還需要一個標誌著序列結束的標誌,也即檔案尾(eof)。

經過我們這樣的分析,那麼書本上的那個問題也就不是文圖了:full和eof是否能夠同時為true?顯然不能,根據我們的設計,只有讀入壞值時eof才為1。

#include <assert.h>
template <typename T>
class Istream_iterator {
        //如何判斷輸入已經結束 當我們的輸入讀入了無效值,那麼我們就認為我們的輸入無效  這個時候full標誌位
        //設定為0 而eof標誌位設定為1 其他情況下 兩者都為0 
		friend int operator== <T> (Istream_iterator<T>& p, Istream_iterator<T>& q)
        {   //到達檔案末尾條件是eof標誌位為1 或者兩個物件屬於同一個物件
            if(p.eof &&q.eof)//都結束了
                return 1;
            if(!p.eof&& !q.eof)//都沒有結束
               return &p == &q;
               /*
               如果有一個結束 另一個沒有結束
               
               */
               p.fill();
               q.fill();
               return p.eof ==q.eof;
        }
		friend int operator!= <T> (Istream_iterator<T>&p, Istream_iterator<T>&q)
        {
            return  !(p == q);    
        }
public:
        //預設呼叫無參建構函式 這個時候不會傳入輸入流 也就是一個空檔案
		Istream_iterator():strm(0), full(0), eof(1)
        {
        }
        //呼叫有參建構函式 這個時候 傳入輸入流
		Istream_iterator(std::istream& is):strm(&is),full(0),eof(0)
        {
            
        }
        //移動到下一個位置,並將full標誌位設定為0
		Istream_iterator& operator++()
        {
            full =0;
            return *this;

        }
		Istream_iterator operator++(int)
        {

            Istream_iterator r = *this;
            full = 0;
            return r;
        }
        //解引用 將相應的值放入快取中
		T operator*(){

            fill();
            assert(full);//????
            return buffer;
        }
       
		void fill()
        {
            if(!full && !eof)//p未結束 q結束了 buffer存值 p結束 q未結束 q繼續輸入 且輸入有效 的時候 會繼續下去
            {
                /*
                 //如果輸入的值無效的時候
                */
                if(*strm >buffer)
                {
                    full = 1;
                }
                  else
                {
                     eof = 1;
                }
        }
private:
		T	buffer;
		std::istream* strm;//輸入流物件
		int full;
		int eof;
};

測試

int main(int argc, char const *argv[])
{

    int y[1000];
    Constant_ierator c(20);
    copyy(c,c+1000,y);
   // cout<<"************"<<encodedl;
    //for(int i =0;i<1000;i++)
   // cout<<y[i]12 <<endl;
    ostream_iterstor<int> z(cout,"**********測試成功*********\n");
    Istream_iterator<int> input(cin);
    Istream_iterator<int> eof;
    copyy(input,eof,z);
     system("pause");
    return 0;
}