I have a linked list that contains a pointer to the first and last node and size which indicates how many nodes are there in the list. I've implemented both Iterator and ConstIterator, ATM ConstIterator only works for const lists, and Iterator for lists, and I want it that Iterator to work for both lists and const lists, this is what I've done so far:
Node
class:
template<class T>
class Node {
public:
Node(const T& t);
~Node()=default; // Destructor set to default
Node(const Node&) = default; // Copy Constructor set to default
Node& operator=(const Node&) = default; // Assignment operator set to default
T& getData();
const T& getData() const;
Node* getNext() const;
void setNext(Node<T>* newNext);
private:
T m_data;
Node* m_nextNode;
};
template<class T>
Node<T>::Node(const T& t) {
this->m_data=t;
this->m_nextNode=nullptr;
}
template<class T>
Node<T>* Node<T>::getNext() const {
return this->m_nextNode;
}
template<class T>
T& Node<T>::getData() {
return this->m_data;
}
template<class T>
const T& Node<T>::getData() const {
return this->m_data;
}
template<class T>
void Node<T>::setNext(Node<T>* newNext) {
this->m_nextNode=newNext;
}
Queue
class:
template<class T>
class Queue {
public:
static const int SIZE_EMPTY=0;
Queue();
~Queue(); // Destructor
Queue(const Queue&); // Copy Constructor
Queue& operator=(const Queue&); // Assignment operator
void pushBack(const T& t);
T& front();
const T& front() const;
void popFront();
int size() const;
class Iterator;
Iterator begin();
Iterator end();
class ConstIterator;
ConstIterator begin() const;
ConstIterator end() const;
class EmptyQueue {};
private:
Node<T>* m_head;
Node<T>* m_tail;
int m_size;
};
template<class T>
Queue<T>::Queue() {
this->m_head=nullptr;
this->m_tail=nullptr;
this->m_size=Queue<T>::SIZE_EMPTY;
}
template<class T>
Queue<T>::~Queue() {
while(this->m_head) {
this->popFront();
}
}
template<class T>
Queue<T>::Queue(const Queue<T>& queue) {
this->m_head=nullptr;
this->m_tail=nullptr;
this->m_size=Queue<T>::SIZE_EMPTY;
for(typename Queue<T>::ConstIterator i = queue.begin();i != queue.end();++i) {
try {
this->pushBack(*i);
} catch(typename Queue<T>::ConstIterator::InvalidOperation& e) {
throw e;
}
}
}
template<class T>
void Queue<T>::pushBack(const T& t) {
try {
Node<T>* newNode=new Node<T>(t);
if(this->m_size==Queue<T>::SIZE_EMPTY) {
this->m_head=newNode;
this->m_tail=newNode;
} else {
this->m_tail->setNext(newNode);
this->m_tail=newNode;
}
this->m_size+=1;
} catch(std::bad_alloc& e) {
throw e;
}
}
Queue<T>::Iterator
class:
template<class T>
class Queue<T>::Iterator {
public:
T& operator*();
Iterator& operator++();
Iterator operator++(int);
bool operator==(const Iterator& iterator) const;
bool operator!=(const Iterator& iterator) const;
Iterator(const Iterator&)=default;
Iterator& operator=(const Iterator&)=default;
class InvalidOperation {};
private:
Node<T>* node;
Iterator(Node<T>* node);
friend class Queue<T>;
};
template<class T>
Queue<T>::Iterator::Iterator(Node<T>* node) {
this->node=node;
}
template<class T>
T& Queue<T>::Iterator::operator*() {
if(this->node==nullptr) {
throw Queue<T>::Iterator::InvalidOperation();
}
return this->node->getData();
}
template<class T>
typename Queue<T>::Iterator& Queue<T>::Iterator::operator++() {
if(this->node==nullptr) {
throw Queue<T>::Iterator::InvalidOperation();
}
this->node=node->getNext();
return *this;
}
template<class T>
typename Queue<T>::Iterator Queue<T>::Iterator::operator++(int) {
if(this->node==nullptr) {
throw Queue<T>::Iterator::InvalidOperation();
}
Iterator result = *this;
++*this;
return result;
}
template<class T>
bool Queue<T>::Iterator::operator==(const Iterator& iterator) const {
return this->node==iterator.node;
}
template<class T>
bool Queue<T>::Iterator::operator!=(const Iterator& iterator) const {
return !(*this==iterator);
}
template<class T>
typename Queue<T>::Iterator Queue<T>::begin() {
return this->m_head;
}
template<class T>
typename Queue<T>::Iterator Queue<T>::end() {
return nullptr;
}
Queue<T>::ConstIterator
class:
template<class T>
class Queue<T>::ConstIterator {
public:
const T& operator*();
ConstIterator& operator++();
ConstIterator operator++(int);
bool operator==(const ConstIterator& constIterator) const;
bool operator!=(const ConstIterator& constIterator) const;
ConstIterator(const ConstIterator&)=default;
ConstIterator& operator=(const ConstIterator&)=default;
class InvalidOperation {};
private:
const Node<T>* node;
ConstIterator(const Node<T>* node);
friend class Queue<T>;
};
template<class T>
Queue<T>::ConstIterator::ConstIterator(const Node<T>* node) {
this->node=node;
}
template<class T>
const T& Queue<T>::ConstIterator::operator*() {
if(this->node==nullptr) {
throw Queue<T>::ConstIterator::InvalidOperation();
}
return this->node->getData();
}
template<class T>
typename Queue<T>::ConstIterator& Queue<T>::ConstIterator::operator++() {
if(this->node==nullptr) {
throw Queue<T>::ConstIterator::InvalidOperation();
}
this->node=node->getNext();
return *this;
}
template<class T>
typename Queue<T>::ConstIterator Queue<T>::ConstIterator::operator++(int) {
if(this->node==nullptr) {
throw Queue<T>::ConstIterator::InvalidOperation();
}
ConstIterator result = *this;
++*this;
return result;
}
template<class T>
bool Queue<T>::ConstIterator::operator==(const ConstIterator& constIterator) const {
return this->node==constIterator.node;
}
template<class T>
bool Queue<T>::ConstIterator::operator!=(const ConstIterator& constIterator) const {
return !(*this==constIterator);
}
template<class T>
typename Queue<T>::ConstIterator Queue<T>::begin() const {
return this->m_head;
}
template<class T>
typename Queue<T>::ConstIterator Queue<T>::end() const {
return nullptr;
}
main
for tests:
Queue<int> queue1;
for (int i = 1; i <= 10; i++) {
queue1.pushBack(i);
}
const Queue<int> constQueue = queue1;
for(Queue<int>::Iterator i = constQueue.begin(); i != constQueue.end(); ++i) {
std::cout << *i << std::endl;
}
Aucun commentaire:
Enregistrer un commentaire