У меня возникают проблемы с простым классом списка Doubly-Linked.
Вот мой код:
/*
* DLList.h
*
* Created on: Nov 19, 2013
* Author: tyler
*/
#ifndef DLLIST_H_
#define DLLIST_H_
#include <iostream>
using namespace std;
template <typename T>
class DLList{
private:
struct DLLNode{
private:
T data_;
bool visited_;
DLLNode* next_;
DLLNode* prev_;
public:
DLLNode(T data){
this->data_ = data;
visited_ = false;
next_ = NULL;
prev_ = NULL;
}
void setData(T data){
this->data_ = data;
}
void visit(){
visited_ = true;
}
void unvisit(){
visited_ = false;
}
void setNext(DLLNode* next){
this->next_ = next;
}
void setPrev(DLLNode* prev){
this->prev_ = prev;
}
T& getData(){
return data_;
}
bool getVisited(){
return visited_;
}
DLLNode* getNext(){
return next_;
}
DLLNode* getPrev(){
return prev_;
}
};
DLLNode* head_;
DLLNode* tail_;
public:
DLList(){
head_ = NULL;
tail_ = NULL;
}
class DLLiterator{
private:
DLLNode* node;
public:
DLLiterator(){
node = head_;
}
T& operator*(const DLLiterator& iter){
return iter.node->getData();
}
DLLiterator& operator++(const DLLiterator& iter){
if(node->getNext() != NULL)
node = node->getNext;
else
node = NULL;
return *this;
}
};
bool isEmpty(){
return (head_ == NULL);
}
void addNodeEnd(T data){
DLLNode* temp = new DLLNode(data);
if(isEmpty()){
head_ = temp;
tail_ = temp;
}
else{
DLLNode* curr;
curr = tail_;
curr->setNext(temp);
temp->setPrev(curr);
tail_ = temp;
}
}
bool contains(T data){
for(DLLNode* start = head_; start != NULL; start = start->getNext()){
if(start->getData() == data)
return true;
}
return false;
}
void remove(T data){
for(DLLNode* curr = head_; curr != NULL; curr = curr->getNext()){
DLLNode* key = curr;
if(curr->getData() == data){
if(curr == head_){
head_ = key->getNext();
key->getNext()->setPrev(NULL);
delete key;
}
if(curr == tail_){
tail_ = key->getPrev();
key->getPrev()->setNext(NULL);
delete key;
}
else{
DLLNode* prev;
DLLNode* next;
prev = key->getPrev();
next = key->getNext();
prev->setNext(next);
next->setPrev(prev);
delete key;
}
}
}
}
void printList(){
for(DLLNode* curr = head_; curr != NULL; curr = curr->getNext()){
cout << curr->getData() << "\n";
}
}
};
#endif /* DLLIST_H_ */
Моя проблема в том, что я не знаю, как на самом деле использовать итератор в внешнем классе. Все остальное проверено и, кажется, работает нормально. Все равно нужно добавить простой деструктор, но сейчас я сосредоточен на итераторе. Любая помощь будет большой.
Я просто пытался:
DLLiterator iter;
но это явно неправильно...
EDIT: теперь это код operator++:
iterator operator++(){
if(node_->getNext() != NULL)
node_ = node_->getNext;
else
node_ = NULL;
return *this;
}
но теперь он просит int
как аргумент...?
Вне класса вам придется использовать квалифицированное имя DLList<whatever>::DLLiterator
. Вы можете видеть, что небольшая точка добавляет бородавку к вложенному имени, если вам не нравятся ваши имена, которые трудно читать: она лишь частично дублирует имя области. Я бы переименовал его в iterator
.
Теперь ваша проблема заключается в том, что он пытается инициализировать себя с помощью члена списка head_
, но у него нет доступа к списку для извлечения главы. Вероятно, вы захотите следовать примеру стандартных контейнеров и создать итератор через член списка:
iterator begin() {return iterator(head_);}
и соответственно измените конструктор итератора.
В С++ 11 это означает, что пользователям обычно не приходится записывать неприятное квалифицированное имя вообще; вы можете получить итератор с
auto it = list.begin();
Наконец, удалите аргументы из operator*
итератора operator*
и operator++
. Поскольку они являются функциями-членами, их операнд передается неявно как this
, а не явно как аргумент.
int
в качестве аргумента ... см. Правку.
++it
. Если вы также хотите постинкремент, it++
, тогда вам также понадобится operator++(int)
. (Пустой аргумент указывает, что это постинкремент, но не имеет никакого другого значения). Для этого потребуется скопировать итератор перед его увеличением и вернуть эту копию по значению.
DLList<int>::iterator iter;
:DLList<int>::iterator iter;
DLList<int>::DLLiterator iter
?