Nov 14, 2008 at 7:57am UTC
I am a newbie in C++. My template classes work fine (at least it seems like so). Now I'd like to make class Iterator an internal class of List. Could you help me on that please?
I have been searching on line for examples but I couldn't find anything to help me understand how it's done.
Below I pasted my list.h and list.cpp files for you to see.
#ifndef LIST_H
#define LIST_H
#include <string>
template <typename T> class Element;
template <typename T> class Iterator;
template <typename T>
class List {
public:
List();
List(const List<T> & other);//copy constructor
~List();
void add(const T& s);
void insert(const Iterator<T>& pos, const T& s);
void remove(Iterator<T>& pos);
void free();
void copy(const List<T>& other);
const List<T> & operator=(const List<T>& other);
Iterator<T> getFirst() const;
Iterator<T> getLast() const;
private:
Element<T>* firstElement;
Element<T>* lastElement;
};
template <typename T>
class Iterator {
public:
Iterator();
T& get() const;
void next();
void prev();
bool equal(const Iterator& b) const;
void operator++(int junk);
void operator++();
T& operator*();
bool operator==(const Iterator& other) const;
bool operator!=(const Iterator& other) const;
private:
Element<T>* position;
Element<T>* last;
friend class List<T>;
};
#endif
/list.cpp
#include "list.h"
#include <string>
#include <iostream>
using namespace std;
template <typename T>
class Element {
public:
Element(const T& s);
private:
T value;
Element<T>* prev;
Element<T>* next;
friend class List<T>;
friend class Iterator<T>;
};
template <typename T>
Element<T>::Element(const T &s) {
value = s;
prev = next = NULL;
}
template <typename T>
Iterator<T>::Iterator() {
position = last = NULL;
}
template <typename T>
T& Iterator<T>::get() const {
return position->value;
}
template <typename T>
void Iterator<T>::next() {
position = position->next;
}
template <typename T>
void Iterator<T>::prev() {
if(position == NULL) {
position = last;
} else {
position = position->prev;
}
}
template <typename T>
bool Iterator<T>::operator ==(const Iterator& other) const {
return (this->position == other.position);
}
template <typename T>
bool Iterator<T>::operator !=(const Iterator& other) const {
return (this->position != other.position);
}
template <typename T>
void Iterator<T>::operator ++(int junk) {
this->position = this->position->next;
}
template <typename T>
void Iterator<T>::operator ++() {
this->position = this->position->next;
}
template <typename T>
T& Iterator<T>::operator *() {
return this->position->value;
}
template <typename T>
bool Iterator<T>::equal(const Iterator& b) const {
return position==b.position;
}
template <typename T>
List<T>::List() {
firstElement = lastElement = NULL;
}
//copy constructor
template <typename T>
List<T>::List(const List<T> & other) {
firstElement = lastElement = NULL;
copy(other);
}
template <typename T>
void List<T>::copy(const List<T>& other) {
if(&other == this) {
return;
}
free();
for(Iterator<T> pos=other.getFirst(); pos!=other.getLast(); pos++ ){
this->add(pos.get());
}
}
template <typename T>
List<T>::~List() {
free();
}
template <typename T>
void List<T>::free() {
for(Iterator<T> pos=this->getFirst(); pos!=this->getLast();){
Iterator<T> temp = pos;
pos++;
this->remove(temp);
}
//important!!
}
template <typename T>
const List<T> & List<T>::operator=(const List<T>& other) {
copy(other);
return *this;
}
template <typename T>
Iterator<T> List<T>::getFirst() const {
Iterator<T> it;
it.position = firstElement;
it.last = lastElement;
return it;
}
template <typename T>
Iterator<T> List<T>::getLast() const {
Iterator<T> it;
it.position = NULL;
it.last = lastElement;
return it;
}
template <typename T>
void List<T>::add(const T& s) {
Iterator<T> last = getLast();
insert(last, s);
}
template <typename T>
void List<T>::insert(const Iterator<T>& pos, const T& s) {
Element<T>* newElement = new Element<T>(s);
if(lastElement==NULL && firstElement==NULL) {
//list is empty
firstElement = newElement;
lastElement = newElement;
} else {
//list is not empety
if(pos.position == NULL) {
lastElement->next = newElement;
newElement->prev = lastElement;
lastElement = newElement;
} else if(pos.position == firstElement){
firstElement->prev = newElement;
newElement->next = firstElement;
firstElement = newElement;
} else {
newElement->next = pos.position;
newElement->prev = pos.position->prev;
pos.position->prev->next = newElement;
pos.position->prev = newElement;
}
}
}
template <typename T>
void List<T>::remove(Iterator<T>& pos) {
if(lastElement==NULL && firstElement==NULL) {
//list is empty, nothing to remove
return;
} else {
//list is not empety
if(pos.position == NULL) {
return;
} else if(pos.position == firstElement){
firstElement = firstElement->next;
} else {
pos.position->prev->next = pos.position->next;
pos.position->next->prev = pos.position->prev;
}
delete pos.position;
}
}
Nov 14, 2008 at 1:54pm UTC
Please use code tags so your code is formatted neatly.
What problems are you having?
I would look at how STL list implements its iterators and follow the same pattern. To make your own iterator that is standards compliant is not easy.