运行定制迭代器的结束

时间:2014-01-20 05:48:46

标签: c++ visual-studio-2010 iterator singly-linked-list

背景

我实现了一个模板化的LinkedList结构。此结构用作单个链接列表,并具有附带的模板化Node类。这两个结构工作正常。但是,我已经工作了一段时间的迭代器有一些“off by 1”错误,并且似乎从List的末尾掉了下来。

代码

这是相关代码(注意:我正在.inl文件中为各种模板化类实现其他模板化方法。我在.hpp中保留迭代器代码,直到我设法让它运行,此时我可以抽象出来。我不相信这个代码结构会产生任何影响,但如果我错了请纠正我。)

LiteNode.hpp

#ifndef LiteNode_H
#define LiteNode_H

#define nullptr 0
template<class LiteNodeType>
class LiteNode
{
private:

    LiteNode* next;
public:
    LiteNodeType data;
    LiteNode(const LiteNodeType& data);
    ~LiteNode();
    LiteNodeType getData(void) const;
    void setNext(LiteNode* next);
    LiteNode<LiteNodeType>* getNext(void);
};

#include "LiteNode.inl"

#endif

LinkedList.hpp

#include "Knight/DataStructures/LiteNode.hpp"
#include <iostream>

#ifndef LINKEDLIST_H
#define LINKEDLIST_H

template<class type>
class LinkedList
{
private:
    LiteNode<type>* head;
    LiteNode<type>* tail;
    int size;
public:
    class Iterator
    {
    private:
        friend class LinkedList;
        LiteNode<type>* elementPtr;
    public:
        Iterator(LiteNode<type>& node)
        {
            elementPtr = &node;
        }
        Iterator(LiteNode<type>* node = nullptr)
        {
            elementPtr = node;
        }
        Iterator& operator++()
        {
            elementPtr = elementPtr->getNext();
            return *this;
        }
        Iterator operator++(int a)
        {
            Iterator retval = *this;
            ++*this;
            return retval;
        }
        type& operator*() const
        {
            type& retVal = elementPtr->data;
            return retVal;
        }

        bool operator==(const Iterator& rhs) const 
        {
            return elementPtr == rhs.elementPtr;
        }
        bool operator!=(const Iterator& rhs) const 
        {
            bool retVal = elementPtr != rhs.elementPtr;
            return retVal;
        }
    };

    LinkedList();
    ~LinkedList();
    void addElement(const type& element);
    void reverse(void);
    void deleteHeadElement(void);
    void printData(void);
    Iterator& start() const
    {
        return Iterator(this->head);
    }
    Iterator& end() const
    {
        return Iterator(this->tail);
    }
};

#include "LinkedList.inl"

#endif

的main.cpp

//Iterator testing
    LinkedList<int>* testList = new LinkedList<int>();
    testList->addElement(10);
    testList->addElement(20);
    testList->addElement(40);
    testList->addElement(60);
    for(LinkedList<int>::Iterator iter = testList->start(); iter != testList->end() ; iter++)
    {
        std::cout << *iter << std::endl;
    }

我尝试过什么

超出界限时得到的输出是

10
20
40
60

因此,由于某种原因,它正在使它结束。我尝试将主代码更改为以下内容:

//Iterator testing
LinkedList<int>* testList = new LinkedList<int>();
testList->addElement(10);
testList->addElement(20);
testList->addElement(40);
testList->addElement(60);
LinkedList<int>::Iterator endIter = testList->end(); //<-- Main change
for(LinkedList<int>::Iterator iter = testList->start(); iter != endIter ; iter++)
{
    std::cout << *iter << std::endl;
}

我得到以下输出(没有崩溃):

10
20
40

我尝试在各种迭代指针和elementPtr变量上设置监视以查看发生了什么,我注意到当我在for循环的比较部分中使用testList-&gt; end()时,其“elementPtr”的值发生了变化到0xcccccccc或其他一些垃圾值。我试着修改增量函数,认为那些可能会调整一些我不想要它的值,但它没有让我到处找。

我真的认为我离这里很近,这里有一些小错误,弄乱了一些东西。我希望一些额外的眼睛可以帮助发现问题。

解决方案(编辑)

好吧,所以Molbdnilo指出了我做错了的一个关键部分。阅读他对解决方案第一部分的回答。除了他提到的东西之外,我必须做的事情是传递一些我知道为null的东西,以便从end()函数产生“理论最后一个元素”。这是一个std :: vector&lt;&gt;页面谈论这个:http://www.cplusplus.com/reference/vector/vector/end/这允许我循环遍历所有元素,而不是错过最后一个,这是我的问题,一旦我修复了我的Iterator()返回类型,如下所述。以下是我修改后的代码:

Iterator start() const
{
    return Iterator(this->head);
}
Iterator end() const
{
    return Iterator(this->tail->getNext());
}

1 个答案:

答案 0 :(得分:3)

这将返回对临时对象的引用,这是一个未定义的操作:

Iterator& start() const
{
    return Iterator(this->head);
}

当函数退出时,您尝试返回引用的对象将被销毁。

你不应该在那里有一个参考:

Iterator start() const
{
    return Iterator(this->head);
}