Absolut ratlos: iterator will nicht so wie ich will.



  • Ich werde es so simpel wie möglich halten:

    Ich habe eine Klasse List die hat eine Methode um einen Iterator auf das erste Element zurückzuliefern:

    [...]
    // first ist vom Typ Node
    inline  Iterator<T> Begin(){ Iterator<T> itTemp(first);  return(itTemp); };
    [...]
    

    Die Iteratorklasse sieht so aus

    [...]
    		Iterator(Node<T> *n){ node = n;	}; // Soll auf einen Knoten zeigen
    		inline T*   operator ->(){ return(&node->GetElement()); };
    
    //	private:
    		Node<T> *node;
    [...]
    

    Und hier der Knoten

    [...]
    		inline T GetElement(){ return(element); };
    
    //	private:
    		Node *prev, *next;
    		T element; // Enthält das eigentliche Element.
    [...]
    

    Soweit, so gut. Ich erstelle mir also eine List<Person> und hänge 3 Einträge an, klappt auch alles super.

    Dann erstelle ich mir einen Iterator auf das erste Element

    List<Person>::iterator itPerson = NULL;
    itPerson = Liste.Begin();
    

    Dann will ich mir die Attribute ausgeben lassen:

    cout<<itPerson->age<<endl; // Typ Integer, funktioniert einwandfrei
    cout<<itPerson->firstName<<endl; // Typ string, Absturz
    

    "Unbehandelte Ausnahme". Mit dem Debugger hab ich schon geschaut, der Iterator zeigt 100% auf das richtige Element und es stehen auch die richtigen Sachen drinne. Nur scheint bei der Ausgabe des strings irgendetwas schiefzugehen,
    da der Absturz in den Funktionen

    strlen()
    std::char_trais<char>::length(const *char)
    std::operator<<() // 1. Version
    std::operator<<() // 2. Version
    

    Ich bin da echt ratlos, ich bete ihr könnt mir helfen 😞 😞



  • Fehler konnte eingegrenz werden, greife ich direkt auf die einzelnen Elemente zu geht es:

    cout<<itPerson.node->GetElement().firstName<<endl;  // Geht
    out<<itPerson.node->element.firstName<<endl;  // Geht
    

    D.h. mein überladener -> Operator muss irgendwie falsch sein:

    inline T*   operator ->(){ return(&node->GetElement()); };
    

    Sieht jemand den Fehler?



  • Dein operator-> gibt die Adresse einer temporären Variablen zurück. Beheben kannst du das, indem du GetElement T& zurückgeben lässt.



  • Du gibst mit GetElement ne Kopie zurück. Die ist dann lokal in Deinem op->, wird also mit Verlassen des op-> zerstört. Der Zeiger zeigt also in's Nichts. Änder mal dne Rückgabewert von GetElement auch zum Beispiel T & oder sowas oder mach nen Pointer draus.

    MfG Jester



  • Ah, danke sehr.

    So sieht das jetzt aus:

    // Node:
    inline T* GetElement(){ return(&element); };
    
    // Iterator:
    inline T*  operator ->(){ return(&node->GetElement());  };
    

    Allerdings habe ich jetzt das Problem das

    cout<<itPerson->firstName<<endl;
    

    sich nicht mehr compilieren lässt:

    **

    inline T*    operator ->(){ return(&node->GetElement());  };
    

    "error C2102: '&' erwartet L-Wert"
    **

    Ich weiß nicht wie ich dann den ->Operator überladen muss, bei allem was ich probiere bekomme ich nur

    **
    error C2819: Der Typ 'Person' hat keinen ueberladenen Elementoperator '->'**

    z.B. bei dieser Variante

    inline T&    operator ->(){ return(node->GetElement());  };
    


  • Ich habe meinen Fehler gefunden, ich habe immer die Adresse von dem Object Person zurückgeben, und dass hatte natürlich keinen -> operator definiert.

    So sieht meine Lösung aus:

    inline T* GetElement(){ T *temp = &element; return(temp); };
    
    inline T*   operator ->(){ return(node->GetElement());  };
    
    cout<<itPerson->firstName<<endl;
    

    Jetzt bin ich mir aber nicht mehr sicher, ich habe doch jetzt einen zeiger temp auf ein Element zeigen lassen. Dann gebe ich die adresse des Objects auf das der Pointer temp zeigt zurück und der Operator -> reicht diese einfach weiter.

    Ist das jetzt so korrekt?



  • Ja, das ist korrekt. Wobei Du Dir im GetElement das temp auch sparen kannst. Ein simples return &element; genügt.

    MfG Jester



  • Stimmt, danke 👍

    😋


Anmelden zum Antworten