我正在学习 C + + ,所以请原谅我这个问题表明我缺乏基础知识,事实上,我缺乏基础知识。
我需要一些帮助来解决如何为我创建的类创建迭代器。
我有一个类“形状”,它有一个点的容器。 我有一个类“件”,它引用了一个形状,并定义了一个形状的位置。 作品没有一个形状,它只是引用一个形状。
我想让它看起来像是一个点的容器,这些点与它所引用的形状相同,但是加上了点位置的偏移量。
我希望能够迭代通过件的点,就像件是一个容器本身。我到处看了看,没有发现任何有用的东西。我会非常感激您的指点。
/编辑: 我明白了,在这里实际上需要一个自己的迭代器(我首先误解了这个问题)。尽管如此,我还是让下面的代码继续存在,因为它可以在类似的情况下派上用场。
这里真的需要一个自己的迭代器吗?也许将所有必需的定义转发给容纳实际点的容器就足够了:
// 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,但是这种类型可以很容易地进行调整。
vector
您的问题的解决方案不是创建您自己的迭代器,而是使用现有的 STL 容器和迭代器。将每个形状中的点存储在一个类似矢量的容器中。
class Shape { private: vector <Point> points;
从那时起你做什么取决于你的设计。最好的方法是迭代通过内部形状方法中的点。
for (vector <Point>::iterator i = points.begin(); i != points.end(); ++i) /* ... */
如果你需要访问塑形之外的点(这可能是一个缺陷设计的标志) ,你可以在塑形方法中创建,它将返回点的迭代器访问函数(在这种情况下也为点容器创建一个公共 typedef)。有关这种方法的细节,请参阅 Konrad Rudolph 的答案。
你可以读这个 DDJ 文章
基本上,从 std: : iterator 继承来完成大部分工作。
你应该用 Boost。迭代器。它包含许多模板和概念,用于为现有迭代器实现新的迭代器和适配器。我已经写了 一篇关于这个主题的文章,它是在2008年12月 ACCU 杂志。它讨论了一个(IMO)优雅的解决方案: 使用 Boost 从对象公开成员集合。迭代器。
如果您只想使用 STL,Josuttis 的书有一章介绍如何实现您自己的 STL 迭代器。
在这里,设计类似 STL 的自定义容器是一篇非常好的文章,它解释了一些基本概念,说明了如何设计一个类似 STL 的容器类以及它的迭代器类。反向迭代器(稍微有点难度)则留作练习: -)
HTH,
用 C + + 编写自定义迭代器可能非常冗长和复杂,难以理解。
由于找不到编写自定义迭代器的最小方法,所以我编写了可能有所帮助的 这个模板标题。例如,要使 Piece类可迭代:
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 equal(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 << p.x << " " << p.y << std::endl; // Output: // 2 3 // 3 4 // 4 5 } return 0; }
它还允许添加其他类型的迭代器,如 const_iterator或 reverse_const_iterator。
const_iterator
reverse_const_iterator
希望能有所帮助。