容器类中的类迭代器

  • 本文关键字:迭代器 容器类 c++
  • 更新时间 :
  • 英文 :


我需要构建一个内部类迭代器来处理容器类FigureOfCircles

#define T Circle
class FigureOfCircles {
private:
Circle* c;
int size;
public:
class Iterator {
protected:
T* t;
public:
explicit Iterator (T* t1 = 0) : t(t1) { }
Iterator (const Iterator& x) : t(x.t)  {}
T& operator*() const { return *t; }
T* operator->() const { return t; }
Circle& operator[](const std::size_t& n) { return t[n]; }
Iterator& operator++() { ++t; return *this; }
Iterator operator++(int) { return Iterator(t++); }
Iterator& operator--() { --t; return *this; }
Iterator operator--(int) { return Iterator(t--); }
Iterator operator- (int n) { return Iterator(t - n); }
Iterator operator+ (int n) { return Iterator(t - n); }
Iterator& operator-= (int n) { t -= n; return *this; }
Iterator& operator+= (int n) { t += n; return *this; }
bool operator== (const Iterator& x) const { return t == x.t; }
bool operator!= (const Iterator& x) const { return t != x.t; }
bool operator<= (const Iterator& x) const { return t <= x.t; }
bool operator> (const Iterator& x) const { return t > x.t; }
bool operator>= (const Iterator& x) const { return t >= x.t; }
bool operator< (const Iterator& x) const { return t < x.t; }
friend int operator- (const Iterator& x, const Iterator& y) { return x.t - y.t; }
Iterator& operator= (const Iterator& x) {
if (t == x.t) exit(-6);
t = x.t;
return *this;
}
};
FigureOfCircles (int sz) : size(sz) {
c = new T[size];
for (Iterator i = begin(); i != end(); ++i) *i = input();
}
FigureOfCircles(const FigureOfCircles& f) {
size = f.size;
c = new T[size];
for (Iterator i = begin(); i != end(); ++i) *i = f.c[i - begin()];
}
~FigureOfCircles() { if (c) delete[] c; }
Circle input() {
int size = 1;
Point* arr = new Point[size];
float r, x1, y1;
cout << endl << "Введiть к-сть точок, радiус i координати центру: ";
cin >> size >> r >> x1 >> y1;
for (int i = 0; i < size; i++) {
Point tmp;
cin >> tmp;
if (tmp.GetX() == x1 && tmp.GetY() == y1) exit(-7);
if (pow(tmp.GetX() - x1, 2) + pow(tmp.GetY() - y1, 2) != r * r) exit(-8);
arr[i] = tmp;
}
return Circle(size, r, arr, x1, y1);        
}
Iterator begin() { return Iterator(c); }
Iterator end() { return Iterator(c+size); }
};

但是我不明白 T 应该是什么类型才能使用迭代器对象?如果是int,那么呢

Iterator begin() { return Iterator(c); }
Iterator end() { return Iterator(c+size); }

注意:

FigureOfCircles (int sz) : size(sz) {
c = new T[size];
for (int i = 0; i < size; i++)
c[i].input();
for (Iterator i = begin(); i != end(); ++i) {
*i = T(i-begin());
}
}

int main () {
//...
FigureOfCircles f(2);
FigureOfCircles::Iterator i;
for (i = f.begin(); i != f.end(); i++) cout << *i << endl;
}

你有一个Circle数组,由c指向。迭代器应指向此数组的元素。最简单的解决方案是使用普通指针。也就是说,迭代器中的T应该只是Circle.

如果你想使用int(应该是std::ptrdiff_t(,你的迭代器还应该保留一个指向第一个元素的指针。在这个特定的例子中,我认为没有理由这样做。

operator-应该返回指针之间的差异,std::ptrdiff_t,而不是Circle

friend std::ptrdiff_t operator-(Iterator x, Iterator y) { 
return x.t - y.t;
}

按价值获取Iterator。它只是一个指针,你不需要通过 const-ref 获取它(有效地获取指向指针的指针(。

拥有迭代器后,您可以使用标准库算法来制作副本:而不是

for (Iterator i = begin(); i != end(); ++i) *i = f.c[i - begin()];

你可以写

std::copy(f.begin(), f.end(), begin());

我建议你用std::vector<Circle>而不是Circle*.然后,您将能够借用其迭代器:

class FigureOfCircles {
private:
std::vector<Circle> c;
public:
std::vector<Circle>::iterator begin() {
c.begin();
}
std::vector<Circle>::iterator end() {
c.end();
}
};

这也将使您免于编写复制构造函数和析构函数。

虽然@Evg的答案是有效的,但从你的问题中不清楚为什么甚至需要编写自己的迭代器。如果您不使用一对指针+长度成员,而是使用std::vectorstd::array- 甚至std::span它不知道您从哪里获取缓冲区 - 您可以使用这些类各自的迭代器而不是实现您自己的迭代器。

只有当你的FigureOfCircles类中有一些特殊的行为——例如元素跳过、非标准迭代顺序等——你才真正需要一个自定义迭代器。

PS - 命名有点尴尬。如果一个图形只能有圆圈,那么只需调用该类Figure。如果有圆圈以外的数字,请尝试:template <typename Element> class Figure { ... },然后您将使用Figure<Circle>

最新更新