创建我自己的迭代器

我正在学习 C + + ,所以请原谅我这个问题表明我缺乏基础知识,事实上,我缺乏基础知识。

我需要一些帮助来解决如何为我创建的类创建迭代器。

我有一个类“形状”,它有一个点的容器。 我有一个类“件”,它引用了一个形状,并定义了一个形状的位置。 作品没有一个形状,它只是引用一个形状。

我想让它看起来像是一个点的容器,这些点与它所引用的形状相同,但是加上了点位置的偏移量。

我希望能够迭代通过件的点,就像件是一个容器本身。我到处看了看,没有发现任何有用的东西。我会非常感激您的指点。

103094 次浏览

/编辑: 我明白了,在这里实际上需要一个自己的迭代器(我首先误解了这个问题)。尽管如此,我还是让下面的代码继续存在,因为它可以在类似的情况下派上用场。


这里真的需要一个自己的迭代器吗?也许将所有必需的定义转发给容纳实际点的容器就足够了:

// 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,但是这种类型可以很容易地进行调整。

您的问题的解决方案不是创建您自己的迭代器,而是使用现有的 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类可迭代:

#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_iteratorreverse_const_iterator

希望能有所帮助。