嗨所以我对于迭代器有点迷茫,他们实际上是....在C++ STL了解迭代
在这种情况下即时通讯使用的名单,我不明白为什么你有什么做一个迭代器:
std::list <int>::const_iterator iElementLocator;
由derefrence运营商dipslay列表的内容:
cout << *iElementLocator;
赋予它也许list.begin后();
请解释什么是一个迭代器,为什么我必须去除它/使用它!
谢谢!
嗨所以我对于迭代器有点迷茫,他们实际上是....在C++ STL了解迭代
在这种情况下即时通讯使用的名单,我不明白为什么你有什么做一个迭代器:
std::list <int>::const_iterator iElementLocator;
由derefrence运营商dipslay列表的内容:
cout << *iElementLocator;
赋予它也许list.begin后();
请解释什么是一个迭代器,为什么我必须去除它/使用它!
谢谢!
有在STL三大基石:
在概念层次的容器保存数据。这本身并不是很有用,因为你想做东西与数据;你想上运行,操纵它,查询它,玩它。算法就是这样做的。但算法不会保存数据,他们没有数据 - 他们需要一个容器来完成这个任务。给容器一个算法,你有一个动作在进行。
要解决的唯一问题是,从技术角度来看,算法如何遍历一个容器。从技术上讲,一个容器可以是一个链表,也可以是一个数组,或二叉树,或任何其他可以容纳数据的数据结构。但遍历一个数组的方式与遍历二叉树不同。尽管在概念上所有算法都需要从容器中一次“获取”一个元素,然后处理该元素,但从容器中下一个元素的操作在技术上非常容器特定。
看起来好像您需要为每个容器编写相同的算法,以便每个版本的算法都具有正确的遍历容器的代码。但是有一个更好的解决方案:请容器返回一个可以遍历容器的对象。该对象将有一个接口算法知道。当算法要求对象“获取下一个元素”时,该对象将符合。由于对象直接来自容器,因此知道如何访问容器的数据。并且由于该对象具有该算法知道的接口,所以我们不需要为每个容器重复一个算法。
这是迭代器。
迭代器在这里胶该算法的容器,没有耦合的两个。一个迭代器被耦合到一个容器,并且一个算法被耦合到迭代器的接口。这里的魔法来源真的是模板编程。考虑标准copy()
算法:
template<class In, class Out>
Out copy(In first, In last, Out res)
{
while(first != last) {
*res = *first;
++first;
++res;
}
return res;
}
的copy()
算法作为参数模板的类型In
和Out
类型的一个迭代两个迭代。它将从位置first
开始并在位置last
之前结束的元素复制到res
中。算法知道获得下一个元素需要说++first
或++res
。它知道要读取一个元素,它需要说x = *first
并写一个元素,它需要说*res = x
。这是接口算法假设和迭代器承诺的一部分。如果错误的迭代器不符合接口,那么当类型未定义函数时,编译器将通过类型In
或Out
发出调用函数的错误。
堆栈溢出问题经常成为谷歌的热门话题,此时回答说:“为什么不谷歌呢”看起来相当短视。 http://meta.stackexchange.com/questions/5280/embrace-the-non-googlers – 2011-04-09 18:39:20
我很懒。因此,我不会键入描述什么是迭代器以及它们是如何使用的,尤其是当已经有很多在线文章可供您阅读时。
这里有一些,我可以引述一开始,proividing的链接来完成的文章:
MSDN说,
迭代器是 指针的推广,从他们的 要求抽象一种允许C++程序以统一的方式与不同的 数据结构一起工作的方式。 迭代器充当容器和通用 算法之间的中介 。而不是在 特定数据类型上运行,算法是 定义为在由迭代器类型指定的范围 上操作。满足迭代器的 要求的任何 数据结构然后可以由算法操作 。有 五种类型或 迭代器的类别[...]
顺便说一句,似乎MSDN采取了文本加粗从C++标准本身,特别是从部分§24.1/ 1,它说:
迭代是 指针,其允许C++程序与以均匀的方式不同的数据结构 (容器) 工作的概括。为了 能够构建模板 算法正确 有效地工作在不同类型的数据 结构,图书馆正式确定不 只是接口也是 语义和复杂的假设迭代 。所有迭代器我支持 表达式* i,导致某个类,枚举或 内置类型T的值为 ,称为迭代器的值类型 。所有用于 的迭代器i其表达式(* i).m为 ,定义明确,支持表达式 i-> m,其语义与 (* i).m相同。对于 的每个迭代类型X,定义了相等性,将有一个 对应的有符号整数类型 ,称为 迭代器的差异类型。
在C++中,一个迭代是任何对象 的是,指向一些元件在 范围的元素(如数组或 的容器)的,有能力到 使用一组运算符(至少为 ,增量(++)和 解除引用(*)运算符)遍历该 范围的元素。
迭代器的最明显的形式是 指针[...]
而且你还可以阅读这些:
请耐心等待并阅读所有这些内容。希望你在C++中能够知道迭代器是什么。学习C++需要耐心和时间。
我建议阅读关于在C++中的运算符重载。这将说明为什么*
和->
基本上可以表示任何事情。只有这样你才能阅读关于迭代器的内容。否则,它可能会显得非常混乱。
迭代器是一个STL容器,指针指向一个数组。您可以将它们视为STL容器的指针对象。作为指针,您可以使用指针表示法(例如*iElementLocator
,iElementLocator++
)。作为对象,他们将拥有自己的属性和方法(http://www.cplusplus.com/reference/std/iterator)。
迭代器与容器本身不一样。迭代器引用容器中的单个项目,并提供到达其他项目的方法。
考虑设计你自己的没有迭代器的容器。它可以有一个size
函数来获取它包含的项目数量,并且可以使[]
运算符超载,以允许您通过其位置获取或设置项目。
但是这种“随机存取”在某些种类的容器上不易实现。如果您获得第百万个项目:c[1000000]
并且容器在内部使用链接列表,则必须扫描一百万个项目才能找到您想要的项目。
您可能决定允许集合记住“当前”项目。它可以像start
和more
和next
功能,让您可以遍历内容:
c.start();
while (c.more())
{
item_t item = c.next();
// use the item somehow
}
但是这使容器内的“迭代状态”。这是一个严重的限制。如果您想将容器中的每件商品与其他商品进行比较,该怎么办?这需要两个嵌套循环,遍历所有项目。如果容器本身存储迭代的位置,则无法嵌套两个这样的迭代 - 内部循环将会破坏外部循环的工作。
所以迭代器是一个迭代状态的独立副本。就可以开始迭代:
container_t::iterator i = c.begin();
即迭代器,i
,是一个独立的对象,表示在容器内的位置。您可以获取任何存储在该位置:
item_t item = *i;
你可以移动到下一个项目:
i++;
有了一些迭代器,你可以跳过前几个项目:
i += 1000;
或者获取相对于迭代器标识的位置的某个位置的项目:
item_t item = i[1000];
并且有些迭代器可以向后移动。
,您可以通过迭代比较end
发现,如果你已经超过容器的内容达成:
while (i != c.end())
你能想到的end
为返回,表示一个位置,是一个超越的迭代器容器中的最后一个位置。
使用迭代器(通常在C++中)要注意的一个重点是它们可能会失效。例如,如果您清空容器,通常会发生这种情况:指向该容器中位置的任何迭代器现在都变得无效。在那个状态下,他们的大部分操作都是未定义的 - 任何事情都可能发生!
+1很好的解释。 – Nawaz 2011-04-09 19:29:03