018
15.08.2005, 08:54 Uhr
FloSoft
Medialer Over-Flow (Administrator)
|
Zitat von (un)wissender: |
Man könnte es so machen, es fehlt aber bei virtuals Code noch das friend, oder ähnliches, weil man sonst nicht an den node im iterator kommt.
C++: |
#include <algorithm> #include <iostream> #include <iterator> #include <memory> #include <stdexcept>
template<typename T> class liste {
struct node { node* prev; node* next; T data; node(const T& data) :prev(this), next(this), data(data) { }
void unlink() { prev->next = next; next->prev = prev; }
void link(node* prev_node) { prev = prev_node; next = prev_node->next; prev->next = this; next->prev = this; } };
node* root;
public: class iterator { friend class liste; //HIER: friend liste* l; node* n;
public: iterator(liste* l=0, node* n=0) :l(l), n(n) { }
T& operator * () { return n->data; } T* operator -> () { return &n->data; } iterator operator ++ (int) { iterator tmp(l,n); if (n) { n = n->next; } return tmp; } iterator& operator ++ () { if (n) { n = n->next; } return *this; } iterator operator -- (int) { iterator tmp(l,n); if (n) { n = n->prev; } return tmp; } iterator& operator -- () { if (n) { n = n->prev; } return *this; } bool operator != (const iterator& other) const { return other.l!=l || other.n!=n; } bool operator == (const iterator& other) const { return other.l==l && other.n==n; } };
liste() { root = std::allocator<node>().allocate(1, 0); root->prev = root->next = root; }
iterator begin() { return iterator(this, root->next); }
iterator end() { return iterator(this, root); }
void push_front(const T& data) { node* n = new node(data); n->link(root); }
void push_back(const T& data) { node* n = new node(data); n->link(root->prev); }
void pop_front() { node* n = root->next; n->unlink(); delete n; }
void pop_back() { node* n = root->prev; n->unlink(); delete n; } void erase(iterator i) { iterator current = begin(), ende = end(); while(current != i && i != ende) ++current; if(current == ende) //nicht gefunden { throw std::invalid_argument("Unknown iterator"); } current.n->unlink(); delete current.n; }
};
int main() { liste<int> list; list.push_back(1); list.push_back(2); list.push_back(3); //@virtual: DAs geht nicht, wegen den fehlenden typedefs "iterator_category, usw." //std::copy(list.begin(), list.end(), std::ostream_iterator<int>(std::cout, " ")); typedef liste<int>::iterator listIter; for(listIter i = list.begin(); i != list.end(); ++i) { std::cout << *i << " "; } list.erase(++list.begin()) ; std::cout << '\n'; for(listIter i = list.begin(); i != list.end(); ++i) { std::cout << *i << " "; } }
|
|
jo das friend hab ich schon bemerkt das fehlt. So in der Art hab ichs mir schon gedacht. Danke. Ich hasse templates :P was ich dafür schon an Zeit verbraucht habe, hätte ich die Liste für die 3 Typen einzeln schreiben können -- class God : public ChuckNorris { }; |