(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;
}