迭代器无法解除引用

时间:2016-11-24 06:27:04

标签: c++ pointers stl iterator

我是C ++的新手,我在完成作业时遇到了麻烦。探究,我有一个类如下:

template<class VertexLabel, class EdgeLabel> class Graph {
public:
    Graph() : id(0){};

    class Vertex {
    private:
        unsigned long id;
        VertexLabel label;
    public:
        Vertex() : label(VertexLabel()){}
        Vertex(VertexLabel lbl) : label(lbl) {};
        const VertexLabel &getLabel() const;
        const VertexLabel &setLabel(const VertexLabel &other);
        const unsigned long &getId() const;
        void setId(unsigned long id);
        ~Vertex(){}
    };

    class Edge {
    private:
        Vertex from, to;
        EdgeLabel edgeLabel;
    public:
        Edge() : from(Vertex()), to(Vertex()), edgeLabel(EdgeLabel()) {};
        Edge(Vertex start, Vertex end) : from(start), to(end), edgeLabel(EdgeLabel()) {};
        Edge(Vertex start, Vertex end, EdgeLabel label) : from(start), to(end), edgeLabel(label) {};
        const Vertex & getFrom() const;
        const Vertex & getTo() const;
        const EdgeLabel& getLabel() const;
        void setLabel(const EdgeLabel& lab);
        ~Edge(){}
    };

    struct VertexPointerComparer {
        bool operator()(const typename std::list<Vertex>::iterator a, const typename std::list<Vertex>::iterator b) const {
            return a ->getId() < b -> getId();
        }
    };

    typedef typename std::list<Vertex>::iterator VertexIterator;

    class EdgeIterator {
    private:
        typename std::list<std::map<typename std::list<Vertex>::iterator, Edge, VertexPointerComparer>>::iterator base;
    public:
        EdgeIterator(typename std::list<std::map<typename std::list<Vertex>::iterator, Edge, VertexPointerComparer>> newBase) : base(newBase.begin()) {}
        bool operator==(const EdgeIterator & other) {
            return base == other.base;
        }
        bool operator!=(const EdgeIterator & other) {
            return base != other.base;
        }
        EdgeIterator & operator++() {
            base++;
            return EdgeIterator(++base);
        }
        EdgeIterator operator++(int) {
            return EdgeIterator(++base);
        }
        EdgeIterator & operator--() {
            base--;
            return *this;
        }
        EdgeIterator operator--(int) {
            return EdgeIterator(--base);
        }
        const Edge & operator*() const {
            const std::map<typename std::list<Vertex>::iterator, Edge, VertexPointerComparer>::iterator iter = base->begin();
            Graph<VertexLabel, EdgeLabel>::Edge next = iter->second;
            return next;
        }
        Edge* operator->() {
            std::map<typename std::list<Vertex>::iterator, Edge, VertexPointerComparer>::iterator iter = base->begin();
            Graph<VertexLabel, EdgeLabel>::Edge next = iter->second;
            return &next;
        }
        virtual ~EdgeIterator() {  }
        typedef std::bidirectional_iterator_tag iterator_category;
        typedef Edge value_type;
        typedef int difference_type;
        typedef Edge * pointer;
        typedef Edge & reference;
    };

    Vertex& addVertex(const VertexLabel& label);
    void addEdge(const Vertex& from, const Vertex & to, const EdgeLabel & label);
    VertexIterator verticesBegin();
    VertexIterator verticesEnd();
    EdgeIterator edgesBegin(const Vertex& v) const;
    EdgeIterator edgesEnd(const Vertex& v) const;
    std::list<std::map<typename std::list<Vertex>::iterator, Edge, 
    virtual ~Graph(){}

private:
    unsigned long id;
    std::list<Vertex> nodes;
    std::list<std::map<typename std::list<Vertex>::iterator, Edge, VertexPointerComparer>> neighbours;
};

我一直在尝试实施方法:

EdgeIterator edgesBegin(const Vertex& v) const;

它应该遍历来自Vertex的所有neighbours并将迭代器返回到来自该顶点的Vertex。这就是我所拥有的:

template<class VertexLabel, class EdgeLabel>
typename Graph<VertexLabel, EdgeLabel>::EdgeIterator Graph<VertexLabel, EdgeLabel>::edgesBegin(const Vertex & v) const
{
    std::list<std::map<typename std::list<Vertex>::iterator, Edge, VertexPointerComparer>> valid;
    std::list<std::map<typename std::list<Vertex>::iterator, Edge, VertexPointerComparer>>::const_iterator i;
    for (i = this->neighbours.begin(); i != this->neighbours.end(); i++) {
        std::map<typename std::list<Vertex>::iterator, Edge, VertexPointerComparer>::const_iterator mapIter = i-> begin();
        std::list<Vertex>::iterator vertex = mapIter->first;
        Edge edge = mapIter->second;
        if (vertex-> getId() == v.getId() && edge.getFrom().getId() == v.getId()) {
            valid.push_back(*i);
        }
    }
    return EdgeIterator(valid);
}

不幸的是,当我试图这样做时:

graph.addEdge(n1, n2, 10.0);
    graph.addEdge(n2, n3, 0.5);
    graph.addEdge(n3, n4, 2.2);
    graph.addEdge(n4, n1, 4.1);
    graph.addEdge(n4, n2, 3.0);
    EdgeIterator edgeIter = graph.edgesBegin(n2);
    std::cout << edgeIter->getFrom().getId();

我收到EdgeIterator无法解除引用的错误。我在调试方面遇到了麻烦(我不知道为什么当我在调试模式下运行时,Visual Studio没有触及我的断点,我已经搜索了主题,但没有任何效果我原因。

我现在已经很久没事了,有人可以帮帮我吗?我怀疑valid对象,即我返回传递给EdgeIterator构造函数的对象在离开方法edgesBegin后被销毁,但我不确定。< / p>

修改 这是恢复这种情况所需的addEdge()方法:

template<class VertexLabel, class EdgeLabel>
void Graph<VertexLabel, EdgeLabel>::addEdge(const Vertex & from, const Vertex & to, const EdgeLabel & label)
{
    std::map<typename std::list<Vertex>::iterator, Edge, VertexPointerComparer> start;
    Edge* edgeA = new Edge(from, to, label);
    Edge* edgeB = new Edge(to, from, label);

    VertexIterator iterStart = this->verticesBegin();
    int advancer = (int)from.getId();
    std::advance(iterStart, advancer);
    start[iterStart] = *edgeA;

    this->neighbours.push_back(start);
}

0 个答案:

没有答案