创build我自己的迭代器

我试图学习C ++,所以原谅我,如果这个问题表明缺乏基本的知识,你看,事实是,我缺乏基本的知识。

我想了解如何为我创build的类创build迭代器。

我有一个“Shape”类,里面有一个Points的容器。 我有一个“Piece”类,它引用了一个Shape并为Shape定义了一个位置。 Piece没有一个Shape,只是引用一个Shape。

我希望它看起来像Piece是一个点的容器,它与它所引用的形状相同,但增加了Piece位置的偏移量。

我希望能够遍历Piece的点,就像Piece本身就是一个容器一样。 我已经做了一些阅读,没有find任何帮助我的东西。 我会非常感谢任何指针。

你应该使用Boost.Iterators。 它包含许多模板和概念来为现有的迭代器实现新的迭代器和适配器。 我写了一篇关于这个话题的文章 。 这是在2008年12月的ACCU杂志。 它讨论了一个(IMO)优雅的解决scheme,正是您的问题:使用Boost.Iterators从对象公开成员集合。

如果你只想使用stl, Josuttis的书有一个实现你自己的STL迭代器的章节。

/编辑:我看到,自己的迭代器实际上是必要的(我误解了第一个问题)。 不过,我还是让下面的代码,因为它可以在类似的情况下有用。


自己的迭代器在这里实际上是必要的吗? 也许把所有必需的定义转发到容器中就足够了:

// Your class `Piece` class Piece { private: Shape m_shape; public: typedef std::vector<Point>::iterator iterator; typedef std::vector<Point>::const_iterator const_iterator; iterator begin() { return m_shape.container.begin(); } const_iterator begin() const { return m_shape.container.begin(); } iterator end() { return m_shape.container.end(); } const_iterator end() const { return m_shape.const_container.end(); } } 

这是假设你在内部使用一个vector但types可以很容易地适应。

在这里devise一个类似于Custom Container的STL是一篇很好的文章,它解释了一些STL类容器类可以和iterator类一起devise的一些基本概念。 反向迭代器(稍微强硬)虽然留作练习:-)

HTH,

你可以阅读这篇ddj文章

基本上,从std :: iteratorinheritance来获得大部分为你完成的工作。

你的问题的解决scheme不是创build你自己的迭代器,而是使用现有的STL容器和迭代器。 将每个形状中的点存储在像vector的容器中。

 class Shape { private: vector <Point> points; 

你从那时起做什么取决于你的devise。 最好的方法是迭代Shape中的方法中的点。

 for (vector <Point>::iterator i = points.begin(); i != points.end(); ++i) /* ... */ 

如果您需要访问Shape之外的点(这可能是一个缺陷devise的标志),您可以在Shape方法中创build将返回点的迭代器访问函数(在这种情况下,还可以为点容器创build一个公共的typedef)。 请看康拉德·鲁道夫(Konrad Rudolph)关于这种方法的详细解答。

使用C ++编写自定义迭代器可能非常冗长而且难以理解。

由于我找不到写一个自定义迭代器的最简单的方法,所以我写了这个模板头文件可能会有所帮助。 例如,要使Piece类可迭代:

 #include <iostream> #include <vector> #include "iterator_tpl.h" struct Point { int x; int y; Point() {} Point(int x, int y) : x(x), y(y) {} Point operator+(Point other) const { other.x += x; other.y += y; return other; } }; struct Shape { std::vector<Point> vec; }; struct Piece { Shape& shape; Point offset; Piece(Shape& shape, int x, int y) : shape(shape), offset(x,y) {} struct it_state { int pos; inline void next(const Piece* ref) { ++pos; } inline void begin(const Piece* ref) { pos = 0; } inline void end(const Piece* ref) { pos = ref->shape.vec.size(); } inline Point get(Piece* ref) { return ref->offset + ref->shape.vec[pos]; } inline bool cmp(const it_state& s) const { return pos != s.pos; } }; SETUP_ITERATORS(Piece, Point, it_state); }; 

那么你将能够使用它作为一个正常的STL容器:

 int main() { Shape shape; shape.vec.emplace_back(1,2); shape.vec.emplace_back(2,3); shape.vec.emplace_back(3,4); Piece piece(shape, 1, 1); for (Point p : piece) { std::cout << px << " " << py << std::endl; // Output: // 2 3 // 3 4 // 4 5 } return 0; } 

它还允许添加其他types的迭代器,如const_iteratorreverse_const_iterator

我希望它有帮助。