c++ - an iterator for an abstract class

2019-07-09 05:36发布

I have an abstract class, for example a class the represents a geometrical shape. I will have concrete classes inheriting from Shape, such as a rectangle and a triangle.

I would like to iterate over the points (another class) a shape is composed of, so Shape must supply an interface for it. The iteration should be in this manner:

for(Point p : shapeObject){ ... some code}

But I don't want the Shape class to determine for the child class what containers to use. For example, a rectangle will have a std::array<Point, 4> container while a triangle will have a std::array<Point, 3> container.

So my question here is, what is the most elegant C++ way to do this?

1条回答
趁早两清
2楼-- · 2019-07-09 05:57

A simple way to solve the "problem"* in the particular case where the points are stored in containers supporting random access iteration (such as std::array or std::vector is to use plain pointers as iterators:

struct Point {};

struct Shape
{
    typedef Point* iterator;
    typedef const Point* const_iterator;
    virtual iterator begin() = 0;
    virtual const_iterator begin() const = 0;
    virtual iterator end() = 0;
    virtual const_iterator end() const = 0;
    virtual ~Shape() {}
};

And have the derived classes implement begin(), end() using pointers to the first and past the end elements of the array they hold.

Alternatively, you could use type-erasure with e.g. boost.any_range or via an any_iterator type. This may be beyond the scope of this answer but here is a good article on precisely this problem.


* That is assuming there really is a problem that requires hiding the type of the iterators. Note that you can also write template code to deal with different iterator types.

查看更多
登录 后发表回答