我实现了一个模板化的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());
}
答案 0 :(得分:3)
这将返回对临时对象的引用,这是一个未定义的操作:
Iterator& start() const
{
return Iterator(this->head);
}
当函数退出时,您尝试返回引用的对象将被销毁。
你不应该在那里有一个参考:
Iterator start() const
{
return Iterator(this->head);
}