2016-11-21 2 views
2

Der folgende Code gibt die Zahlen von 0 bis 9 mit benutzerdefinierten Iteratoren aus. Ich kompilieren mit g++ -std=c++11 -o test test.cppC++ - benutzerdefinierter Iteratorkonstruktor

#include <iostream> 

class some_class; 

class some_class_iterator : public std::iterator<std::forward_iterator_tag, int>{ private:  
    friend class some_class; 
    int pointed; 
    some_class_iterator(int _pointed): pointed(_pointed){ 
     std::cout << "over here" << std::endl; 
    } 

public: 
    int poitned; 

    int operator*(){ 
     return pointed; 
    } 

    const some_class_iterator& operator++(){ 
     pointed++; 
     return *this; 
    } 

    bool operator!=(const some_class_iterator& other) const { 
     return this->pointed != other.pointed; 
    } 

}; 

class some_class{ 
public: 
    typedef some_class_iterator iterator; 

    iterator begin(){ 
     return some_class_iterator(0); 
    } 

    iterator end(){ 
     return some_class_iterator(10); 
    } 

}; 


int main(){ 

    some_class a; 
    for (some_class::iterator i = a.begin(); i != a.end(); ++i) std::cout << *i << std::endl; 

} 

jedoch der Ausgang nicht, was ich zu erwarten sein als over here mehrfach gedruckt wird. Zum Beispiel aktuelle Ausgabe lautet:

over here 
over here 
0 
over here 
1 
over here 
2 
over here 
3 
over here 
4 
over here 
5 
over here 
6 
over here 
7 
over here 
8 
over here 
9 
over here 

Also, wer den Anruf auf dem Konstruktor hier verursacht?

Mein aktuelles Problem ist auf einem binären Suchbaum Iterator, wo im Konstruktor ich eine FIFO-Traversal mit den zu druckenden Knoten abhängig von (in, vor, nach) erstellen, so den Konstruktor mehrere Male aufrufen ist costy.

Antwort

3

Jede Iteration Ihrer Schleife rufen Sie a.end(), die einen neuen Iterator erstellen und "hierhin" drucken wird. Sie können den Wert von _pointed ausdrucken, um dies zu sehen. (Das erste "hier drüben" kommt vom begin Anruf).

+0

* High Five! * ... und etwas Fülltext. –

+0

Hoppla ... nun, das war eine fehlschlagende Frage ... –

+1

@k_kaz Nein, du hast eine Inspiration für zukünftige Debugging-Techniken, also ist es am Ende ein bisschen ein Gewinn. –

1

Jedes Mal, wenn Sie die Bedingung in Ihrer for-Schleife überprüfen, rufen Sie end() auf, wodurch ein neuer Iterator erstellt wird.

Wenn Sie pointed_ zu Ihrer Debug-Ausgabe hinzufügen, kann es helfen, solche Dinge zu verfolgen. So können Sie Ihren anderen Aufrufen Ausdrucke hinzufügen und auch in einem Debugger durchgehen.

Um es zu vermeiden, könnten Sie das Ende vor der for-Schleife cachen, aber das ist komisch und passt nicht zum üblichen Muster für das Schleifen mit Iteratoren. Eine bessere Lösung könnte sein, das Ende als ein Mitglied in Ihrer Klasse zu speichern und end() einen Verweis darauf zurückgeben, oder zu sehen, ob Sie einen Weg finden können, den Iteratoraufbau in Ihrem echten Programm weniger kostspielig zu machen.

+0

Wenn some_class :: end() diese const-Referenz zurückgibt, von der Sie sprechen, wäre das ein besseres Design? –

+0

@k_kaz Ja, das wäre eine gute Option. –

Verwandte Themen