The old const pointer problem

I am writing a Polygon class. The idea is that it should be immutable: ie, you specify the vertices at construction, and then it cannot be modified. I need to be able to iterate over both vertices and edges, and so to prevent redundantly storing the vertices I used a vector of pointers to vertices that make up the edges. Here is my code:

Polygon.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#pragma once
#include "Vector2D.h"
#include <vector>
#include <utility>
using namespace std;

class Polygon {
private:
    vector<Vector2D> _vertices;
    vector<pair<Vector2D*, Vector2D*> > _edges;
public:
    Polygon(const vector<Vector2D>& vertices);
    vector<Vector2D>::const_iterator vertexBegin() const;
    vector<Vector2D>::const_iterator vertexEnd() const;
    vector<pair<Vector2D*, Vector2D*> >::const_iterator edgeBegin() const;
    vector<pair<Vector2D*, Vector2D*> >::const_iterator edgeEnd() const;
};


Polygon.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include "Polygon.h"
#include "assert.h"

Polygon::Polygon(const vector<Vector2D>& vertices) :
    _vertices(vertices) {
    //A polygon must have at least 3 vertices
    assert(vertices.size() > 2);

    //Build the edges vector
    Vector2D* prev = &(*_vertices.begin());
    for (vector<Vector2D>::iterator iter = _vertices.begin() + 1; iter != _vertices.end(); ++iter) {
        _edges.push_back(pair<Vector2D*, Vector2D*>(prev, &(*iter)));
        prev = &(*iter);
    }
}

vector<Vector2D>::const_iterator Polygon::vertexBegin() const {
    return _vertices.begin();
}

vector<Vector2D>::const_iterator Polygon::vertexEnd() const {
    return _vertices.end();
}

vector<pair<Vector2D*, Vector2D*> >::const_iterator Polygon::edgeBegin() const {
    return _edges.begin();
}

vector<pair<Vector2D*, Vector2D*> >::const_iterator Polygon::edgeEnd() const {
    return _edges.end();
}


The problem I am having is that using the edge iterator I can now edit the vertices in my polygon. For example, I can do the following:

1
2
3
4
5
6
7
8
vector<Vector2D> points;
points.push_back(Vector2D(12,12));
points.push_back(Vector2D(13,13));
points.push_back(Vector2D(14,14));
Polygon poly(points);

vector<pair<Vector2D*, Vector2D*> >::const_iterator iter = poly.edgeBegin();
(*iter).first->setX(5);


Ideally, I would like the return type of my edge iterator to be something like
 
const vector<const pair<const Vector2D* const, const Vector2D* const> >

but it seems really difficult or at least inefficient to achieve this conversion.

Can someone suggest how this conversion can be achieved, or perhaps an alternative method of making my Polygon immutable and still providing access to the edges and vertices? I will also be thankful for any general advice on refactoring this code.
Why not implement your own iterator that does just that when dereferenced?
For example,
1
2
3
4
std::pair<const Vector2D *,const Vector2D *> VectorIterator::deref(){ //I can't remember the syntax for the dereference operator
	std::pair<Vector2D *,Vector2D *> &element=this->polygon._edges[this->position];
	return std::pair<const Vector2D *,const Vector2D *>(element.first,element.second);
}
Topic archived. No new replies allowed.