我需要构建一个内部类迭代器来处理容器类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::vector
或std::array
-甚至是std::span
,而忽略了从何处获取缓冲区,则可以使用这些类各自的迭代器代替实现自己的。
[仅当您在FigureOfCircles
类中有某些特殊行为时-例如跳过元素,非标准的迭代顺序等-确实需要自定义迭代器。
PS-命名有点尴尬。如果一个图形只能有圆,则只需调用类Figure
。如果有圆形以外的图形,请尝试:template <typename Element> class Figure { ... }
,然后将使用Figure<Circle>
。