iterator的用法?

petsatan 2009-03-14 06:06:54
class CTest
{
public:
virtual void prn();
}
class CTestText : public CTest
{
public:
void prn();
}

vector<CTest> pTest;

for( vector<CTest>::iterator it = pTest.begin(); it != pTest.end(); ++it )
{
//怎么访问CTestText 中的prn();
it->prn(); 访问是CTest中的
}

...全文
10318 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
WalterLee 2010-06-28
  • 打赏
  • 举报
回复
长见识了,谢谢大家
timeMem 2009-11-21
  • 打赏
  • 举报
回复
kh
cpp255 2009-04-26
  • 打赏
  • 举报
回复
学习了
mengde007 2009-03-14
  • 打赏
  • 举报
回复
建议看看stl!
tangshuiling 2009-03-14
  • 打赏
  • 举报
回复

简单的一句话:凡想表现类继承中虚函数的行为,非指针和引用,其它的形式不可为之
KevinYuen 2009-03-14
  • 打赏
  • 举报
回复
隐藏数据结构,方便提供对外统一数据访问方法的 迭代器模式,具体的可以参考实际代码或者设计模式的书籍。
grellen 2009-03-14
  • 打赏
  • 举报
回复
用指针就行了
#include<iostream>
#include<vector>
using namespace std;
class CTest
{
public:
virtual void prn(){cout<<"text"<<endl;};
};
class CTestText : public CTest
{
public:
void prn(){cout<<"CTestText"<<endl;};
};
int main()
{
vector<CTest*>pTest;
for(int i = 0; i < 10; i++)
{
if(i%2==0)
{
CTest *p = new CTestText();
pTest.push_back(p);
}
else
{
CTest *p = new CTest();
pTest.push_back(p);
}
}
for( vector <CTest*>::iterator it = pTest.begin(); it != pTest.end(); ++it )
{
(*it)->prn();
}

}
zhaohongbo83 2009-03-14
  • 打赏
  • 举报
回复
vector <CTestText > pTest;
试一下,楼上说的很对
  • 打赏
  • 举报
回复
vector <CTest> pTest;

pTest是一个指向CTest类型数据的容器,里面的数据全是CTest的实例,而CTest是父类,而你要访问CTestText 中的prn();肯定不可以的,CTestText 这部分都没用被实例化。
vector <CTestText > pTest; 还差不多。
ayw215 2009-03-14
  • 打赏
  • 举报
回复
lz的错误不是在于不会用iterator
注意,你的vector里面存放的是ctest的对象,当你把一个CTestText对象push进去后,push的是这个对象的一个副本,同时,这里会对对象进行split。
此时你要访问CTestText重写的虚函数的话是不会成功的,因为这个时候根本不会出现多态。

解决的办法很简单:
vector里面存放ctest的指针即可
ypb362148418 2009-03-14
  • 打赏
  • 举报
回复
这个东西也算容器里的一个,叫做迭代子,相当于指针,里面有一个近似于智能指针的东西,这个迭代子的功能主要是遍历一个容器里的所有内容,并且可以作出相应的操作
chin_chen 2009-03-14
  • 打赏
  • 举报
回复
Iterator模式的几种用法
在网络上看帖子时发现不少模式的初学者对Iterator模式的理解仅仅停留在从类库的容器类取得Iterator来遍历容器中的内容的程度。
因此在这里写几个例子,来加深大家对Iterator模式的理解。

对容器中元素的访问涉及到3个方面。
1.容器的类型
2.检索容器内元素的方法
3.对元素的操作
比如说我们有一个表示书店的book_store类。里面保存了各种各样的book类的实例。
book类有name和type两种属性。表示书的名字和类别。
因此book_store类内部会用一个容器来保存book的实例。比如list。
class book
{
public:
string name;
string type;
};

class book_store
{
private:
list<book> m_books;
};

我们现在有这样一个简单的应用,那就是输出所有的书名到屏幕。
那么我们来看一下在引入Iterator模式前有那几种实现方法,各有什么缺点。
1.给book_store类增加一个print_book_name的函数。来实现这个功能。
这样做的缺点有两个:
(1).将输入输出逻辑和业务对象绑定在一起,导致了今后系统难以变更。
(2).输出逻辑和内部实现绑定。
比如现在要把输出到屏幕改成输出到log文件的话,那么就需要修改print_book_name了。
2.给book_store类增加一个get_list函数。然后写一个print_book类来负责打印书名的列表。这是一个初学者常用的方式。表面上看来似乎两个类各担其责,一个表示业务对象一个负责打印。
如果需要打印到log文件的话,只要新增加一个log_book类,book_store和print_book都不受影响。解决了上面的这个问题。
这样做的缺点是:
(1).把book_store类的内部实现给暴露出来了,违反了封装的原则。
如果现在把内部容器类型从list换成了vector的话,就要修改输出逻辑了。也就是说,要同时改写print_book类和log_book类。
3.增加一个list和vector类共同的基类/接口,比如I_container。然后给book_store类增加一个get_books函数,返回I_container。
这在一定程度上解决了上面的问题。但是并不彻底。应为还是暴露了内部的实现,只不过从list上升到了I_container。
· 如果现在系统发生了变化,book_store不再在本地保存books了,而是需要通过网络取得的话,print_book和log_book就无法对应了。
· 另一个限制是,我需要一个新的机能,那就是打印所有type为”烹饪书”的机能的话,就需要一个print_cook_book类了,而这里边的格式化代码和输出代码和print_book是相同的。重复代码是维护的噩梦。

接下来我们看一下Iterator模式如何解决以上的这些问题。
首先,我们引入一个I_iterator的Interface。
然后创建一个I_iterator的实现类all_book_iterator。这个类可以迭代book_store中的所有book。
接下来创建一个print_book类,从I_iterator中取得每一个book,然后打印到屏幕。

下面我们看一下如何对应上面的这些需求变更。
1.要求输出到log文件
追加一个log_book类,其他都类都不需要改变。
2.将内部容器从list变成vector。
修改iterator中的相关代码。Iterator的使用者不会受到影响。
3.从网络取得数据。
修改iterator中的相关代码。Iterator的使用者不会受到影响。
4.按照type检索
在iterator中添加一个type的属性,或者是构造一个新的type_search_iterator。
在iterator中把不符合检索条件的book过滤掉。
5.按照某一特定顺序输出book名到屏幕,或是log文件。
实现一个按该顺序输出的iterator。
6.以同样的方式打印cd_store。
实现对应于cd_store的iterator。

可见,iterator模式在各种iterator中封装了检索元素的方法。
将容器和对容器中元素的操作完全隔开。
大大增加了代码的可重用性
chin_chen 2009-03-14
  • 打赏
  • 举报
回复
erator的概念源自于对遍历一个线性容器工具的抽象,即如何你能访问这个容器的某个元素。对于最简单的数组,当然可以用数组的索引值,因为数组是连续存放在内存中的;但对于链表,就必须用指针。除此之外,还有还有很多种数据结构需要提供一个方便的工具来访问其中的元素,方法有ID,关键字等等。为了统一所有的容器的这种工具的使用,一般提供一整套容器的开发者就会用一种方式来表示各种容器的访问工具。例如C++ STL就是使用iterator。MFC自己的容器使用position。C#和java也有自己的方法,但方法是不变的。
iterator的用法可以被统一,但不同的底层容器实现其iterator的原理是不一样的。例如iterator++你可以理解为移动到容器的下一个元素,如果底层如果是数组,把索引值加一就行;如果底层是链表,就得执行类似于m_pCurrent = m_pCurrent->pNext;的操作。因此每种容器都有自己的iterator实现方法。
C++ STL iterator的常用方法有:
iterator++ 移到下个元素
iterator-- 移到上个元素
*iterator 访问iterator所指元素的值]
< > == != iterator之间的比较,例如判断哪个元素在前
iterator1 + iterator2 iterator之间的加法运算,类似于指针加法
chin_chen 2009-03-14
  • 打赏
  • 举报
回复
iterator是容器的一个成员,相当于指针,但是比指针功能多啊!

65,211

社区成员

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

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