2010-12-01 5 views
5

J'essaie de trouver un ou deux choses:opérateur Increment/mise en œuvre iterator

  1. Comment puis-je écrire un opérateur d'incrément pour une classe de noeud qui a un pointeur vers le nœud suivant?
  2. Comment implémenter des itérateurs pour une classe comme ci-dessous?

    #include <iostream> 
    #include <vector> 
    using namespace std; 
    
    template <typename T> 
    class Node { 
    public: 
        Node(int i=0):val(i) {} 
        Node*& operator++(int i=0) {return next;}; 
    
        T val; 
        Node *next; 
    }; 
    
    //================================================ 
    int main() { 
    
        Node<int> *head, *tmp1, *tmp2; 
    
        tmp1 = new Node<int>(0); 
        head = tmp1; 
    
        for (int i=1; i<10; ++i) { 
    
         tmp2 = new Node<int>(i); 
         tmp1->next = tmp2; 
         tmp1 = tmp2; 
        } 
    
        while (head != NULL) { 
    
         cout << head->val << " '"; 
         head = head->operator++(0); //How do I make it work with ++head;? 
        } 
    } 
    

Ce n'est pas un bon exemple pour démontrer la surcharge des opérateurs ou itérateurs.

+3

Vous ne pouvez pas. head est un pointeur et l'opérateur ++ est intégré/défini pour les pointeurs. Si la tête était un objet ou une référence à un objet, alors vous pourriez le faire. –

+0

hmm..okay. Connaissez-vous des liens vers l'implémentation d'itérateurs? Merci vous – blueskin

+0

Vous pouvez regarder les réponses à cette question: http://stackoverflow.com/questions/3582608/how-to-correctly-implement-custom-iterators-and-const-iterators –

Répondre

10

Vous n'implémentez pas operator++ pour la classe de nœud; vous l'implémentez pour l'itérateur. La classe itérateur doit être une classe distincte.

Et s'il vous plaît, ne pas gâcher votre modèle en faisant des hypothèses (depuis val est un T, votre constructeur devrait accepter un T, pas int). De plus, n'ignorez pas le paramètre int de l'opérateur ++ comme cela: c'est un mannequin utilisé pour distinguer l'implémentation de pré-incrémentation de l'implémentation post-incrément.

template <typename T> 
struct Node { 
    T val; 
    Node *next; 

    Node(const T& t = T()) : val(t) {} 
}; 

template <typename T> 
struct node_iter { 
    Node<T>* current; 
    node_iter(Node<T>* current): current(current) {} 

    const node_iter& operator++() { current = current->next; return *this; } 
    node_iter operator++(int) { 
     node_iter result = *this; ++(*this); return result; 
    } 
    T& operator*() { return current->val; } 
}; 

int main() { 
    // We make an array of nodes, and link them together - no point in 
    // dynamic allocation for such a simple example. 
    Node<int> nodes[10]; 
    for (int i = 0; i < 10; ++i) { 
     nodes[i] = Node<int>(i); 
     nodes[i].next = (i == 9) ? nodes + i + 1 : 0; 
    } 

    // we supply a pointer to the first element of the array 
    node_iter<int> test(nodes); 
    // and then iterate: 
    while (test.current) { 
     cout << *test++ << " "; 
    } 
    // Exercise: try linking the nodes in reverse order. Therefore, we create 
    // 'test' with a pointer to the last element of the array, rather than 
    // the first. However, we will not need to change the while loop, because 
    // of how the operator overload works. 

    // Exercise: try writing that last while loop as a for loop. Do not use 
    // any information about the number of nodes. 
} 

Ceci est encore un long, loin de fournir l'encapsulation des données, une gestion de la mémoire, etc. Faire une classe de liste chaînée est correcte pas facile. C'est pourquoi la bibliothèque standard en fournit un. Ne réinventez pas la roue.

+0

Je me suis rendu compte qu'après avoir posté ceci. J'essayais en fait de comprendre comment implémenter les itérateurs, c'est un mauvais exemple que j'ai donné. Je pense que QList est bien implémenté par rapport à la liste STL. Je vais essayer de mettre en œuvre quelque chose comme ça. Merci Karl – blueskin

+2

http://en.literateprograms.org/Singly_linked_list_%28C_Plus_Plus%29 est plus utile – blueskin

+1

Pourquoi l'opérateur ++() renvoie une référence const et l'opérateur ++ (int) renvoie une valeur? –