请教:c++ iterator 是如何用c++语言实现的?

liufeng_cp 2007-12-05 09:32:54
我能理解iterator,也会使用,但是却无法理解它在c++里面是怎么实现的;
类似于list<int>::iterator it的声明;我找不到一个语法上的解。
小弟想请教各位大哥。
谢谢
...全文
1572 13 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
yshuise 2007-12-05
  • 打赏
  • 举报
回复
从代码看来,是类不是指针
wpalhm 2007-12-05
  • 打赏
  • 举报
回复
stl的源代码都是公开的.可是上网去查看它的源代码.
wpalhm 2007-12-05
  • 打赏
  • 举报
回复
接着可以定义List_iterator,实现迭代器的操作"++","--","*"

template <typename T, typename Ref, typename Ptr>
struct List_iterator : public List_iterator_base
{
typedef ...
...
//构造函数
List_iterator(Node* x) : List_iterator_base(x) {}
List_iterator() {}
List_iterator(const iterator& x) : List_iterator_base(x.Mode) {}
//operator *(), ++(), --()
referenc operator*() const ...
pointer operator->() const ...
Self& operator++()...//前自加
Self& operator++(int)...//后自加
Self& operator--()...
Self& operator--(int)...
};
wpalhm 2007-12-05
  • 打赏
  • 举报
回复
我们可以用struct来创造双向链表的迭代器iterator

struct List_node_base
{
List_node_base* M_next;
List_node_base* M_prev;
};
template <typename T>
struct List_node : public List_node_base
{
T M_data;
};
struct List_iterator_base
{
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef bidirectional_iterator_tag iterator_category;
//当前节点的位置,不采用List_node*,节省内存
List_node_base* M_node;
//构造函数
List_iterator_base(List_node_base* x): M_node(x) {}
List_iterator_base() {}
//提供迭代器移动的操作函数
void M_incr() { M_node = M_node->M_next;}
void M_decr() { M_node = M_node->M_prev;}
//operator==()函数
bool operator==(const List_iterator_base& x)const
{
return M_node == x.M_node;
}
//operator!=()函数
bool operator!=(const List_iterator_base& x)const
{
return M_node != x.M_node;
}
};
liufeng_cp 2007-12-05
  • 打赏
  • 举报
回复
谢谢
我刚刚找到stl源码看了下
知道怎么弄了
iambic 2007-12-05
  • 打赏
  • 举报
回复
模板+操作符重载。可以看看STL源码。
liufeng_cp 2007-12-05
  • 打赏
  • 举报
回复
我知道这是指针,问题是,假如c++不提供这样的模板
自己来做的话,怎么办
如何实现Container <Type> ::iterator 这种类型(加上域的iterator类型)
我构造不出这样的模板
babyvox1999 2007-12-05
  • 打赏
  • 举报
回复
指针
liufeng_cp 2007-12-05
  • 打赏
  • 举报
回复
不好意思,刚刚发错了
刚刚是我最初尝试失败的代码
看了代码后,后来实现的是这样



#include <iostream>
using namespace std;

template <class T>
class my_iterator{
//friend class my_iterator;
public:
my_iterator(T *value=NULL){_value=value;}
//~my_iterator()//该不该加?
//{
//}

T& operator*() const{return *_value;}
T* operator->() const{return _value;}//用于返回内容

//++(当iterator移动的时候,移动的是其内封装的值)
my_iterator& operator++()
{
_value=_value->next;
return *this;
}

bool operator==(my_iterator& other){return _value==other._value;}
bool operator!=(my_iterator& other){return _value!=other._value;}

protected:
T *_value;
};

template <class T>
class my_node{
public:
my_node():next(NULL){}
my_node(T& v):value(v),next(NULL){}

T value;
my_node *next;
};

template <class T>
class my_list{
public:
//定义iterator
typedef my_iterator< my_node<T> > my_iterator;

public:
my_list():_size(0),_pnode(NULL){}

//获得元素个数
int size(){return _size;}

//清空
void clear()
{
my_node<T>* p;
while(_pnode)
{
p=_pnode;
_pnode=_pnode->next;
delete p;
}
_size=0;
}

//获得首元素
my_iterator& begin()
{
my_iterator *pit=new my_iterator(_pnode);
return *pit;
}

//获得尾元素
my_iterator& end()
{
my_node<T>* p=_pnode;
while(p) p=p->next;
my_iterator *pit=new my_iterator(p);
return *pit;
}

//添加元素
void push_back(T value)//后插
{
my_node<T> *p=new my_node<T>(value);
if(_pnode){
my_node<T> *pt=_pnode;
while(pt) pt=pt->next;
pt->next=p;
}else{
_pnode=p;
}
_size++;
}
void push_front(T value)//前插
{
my_node<T> *p=new my_node<T>(value);
if(_pnode){
p->next=_pnode;
_pnode=p;
}else{
_pnode=p;
}
_size++;
}

//删除
T pop_back()//后取
{
my_node<T> *p=_pnode;
my_node<T> *tail;
T value;
if(!p) throw("NULL");
else if(!p->next)
{
T value=p->value;
delete p;
_size--;
_pnode=NULL;
return value;
}
while(p && p->next && p->next->next) p=p->next;
value=p->next->value;
delete p->next;
p->next=NULL;
_size--;
return value;
}
T pop_front()//前取
{
my_node<T> *p=_pnode;
T value;
if(!p) throw("Exception: the list is NULL!");
_pnode=_pnode->next;
value=p->value;
delete p;
_size--;
return value;
}

//

protected:
my_node<T> *_pnode;
int _size;

};

//重载输出
template <class T>
ostream& operator<<(ostream& ost,my_list<T> lst)
{
my_list<T>::my_iterator it;
if(lst.size()>0){
for(it=lst.begin();it!=lst.end();it++)
{
cout<<it->value<<endl;
}
}else{
cout<<"NULL"<<endl;
}

return ost;
}

//===================自定义find算法
template <class T,class Value>
T my_find(T begin,T end,Value value)
{
T it;
for(it=begin;it!=end;it++)
{
if(it->value==value) break;
}

return it;
}

int main(int argc, char* argv[])
{
//测试int
my_list<int> lst;
lst.push_front(1);
lst.push_front(2);
lst.push_front(3);
lst.push_front(4);
lst.push_front(5);
cout<<lst<<endl;
lst.pop_front();
lst.pop_back();
cout<<lst<<endl;
lst.clear();
cout<<lst<<endl;
try{
lst.pop_front();//将发生异常
}catch (char *e) {
cout<<e<<endl;
}
//测试double
my_list<double> lst1;
lst1.push_front(1.0);
lst1.push_front(2.2);
lst1.push_front(3.3);
lst1.push_front(4.0);
lst1.push_front(5.7344);
cout<<lst1<<endl;
lst1.pop_front();
lst1.pop_back();
cout<<lst1<<endl;
lst1.clear();
cout<<lst1<<endl;
try{
lst1.pop_front();//将发生异常
}catch (char *e) {
cout<<e<<endl;
}

//测试find函数
int i;
for(i=0;i<20;i++)
{
lst.push_front(i);
lst1.push_front(i+0.5);
}
my_list<int>::my_iterator it1;
my_list<double>::my_iterator it2;
it1=my_find<my_list<int>::my_iterator,int>(lst.begin(),lst.end(),5);
it2=my_find<my_list<double>::my_iterator,double>(lst1.begin(),lst1.end(),5.5);

cout<<it1->value<<endl;
cout<<it2->value<<endl;

return 0;
}


liufeng_cp 2007-12-05
  • 打赏
  • 举报
回复
谢谢这么多人回复。
中午吃过饭我自己写了个简单的list试了下。基本搞明白了~~



/***********************************
* 模拟了一个简单的list和其迭代器
***********************************/
#include<iostream>
#include<cassert>

using namespace std;

template<class T>
class List{
typedef struct _Node{
_Node():pre(NULL),next(NULL){};
_Node(const T& val):value(val),pre(NULL),next(NULL){};

T value;
_Node *pre;
_Node *next;
} Node,*PNode;
public:
typedef PNode itr;

public:
//构造函数
List():_size(0),_head(NULL),_tail(NULL)
{
}
List(int size):_size(size)
{
for(int i=0;i<_size;i++){
PNode node=new Node();
node->next=_head;
_head.pre=node;
_head=node;
if(_head->next) _tail=_head;
}
}


int size() const{return _size;}
void push_back(const T& value)
{
PNode node=new Node(value);
node->next=_head;
if(_head) _head->pre=node;
_head=node;
if(!_head->next) _tail=_head;
_size++;
}
void push_front(const T& value)
{
PNode node=new Node(value);
if(_tail) _tail.next->node;
node->pre=_tail;
_tail=node;
if(!_tail->pre) _head=_tail;
_size++;
}
void clear()
{
PNode temp;
while((temp=_head)){
_head=_head->next;
delete temp;
}
_head=NULL;
_tail=NULL;
_size=0;
}
void dump() const
{
PNode temp=_head;
while(temp){
cout<<temp->value<<endl;
temp=temp->next;
}
}
itr begin() const
{
return _head;
}
itr end() const
{
return _tail;
}

private:
int _size;
PNode _head;
PNode _tail;
};


template<class T>
ostream& operator<<(ostream& pst,List<T> &list)
{
cout<<"the list size is:"<<list.size()<<endl;
list.dump();
return pst;
}

int main(int argc, char* argv[])
{
List<int> list;
list.push_back(0);
list.push_back(1);
list.push_back(2);
cout<<list<<endl;
List<int>::itr it=list.begin();
cout<<it->value<<endl;
list.clear();
cout<<list<<endl;
return 0;
}
yutaooo 2007-12-05
  • 打赏
  • 举报
回复
更正一下:指针是一种iterator, 但是iterator绝对不不不等同于指针。

抱歉。
yutaooo 2007-12-05
  • 打赏
  • 举报
回复

指针是一种iterator, 但是iterator绝对等同于指针。指针可以是迭代器的一种实现,但是迭代器可以用其它方式实现,比如实现了operator*,operator++等操作的类。

另外提一句,指针失效和迭代器失效,不相等。


iambic 2007-12-05
  • 打赏
  • 举报
回复
list的iterator当然不是指针。

65,186

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧