Zeiger auf Ende einer Objektkette setzen



  • @CTecS Danke CTecS! Genau das war auch mein ursprünglicher Gedanke es so zu machen, hier stoße ich nur auf das Problem mit der Fehlermeldung (@Manni: Sorry dafür, Fehlermeldung unten). Heißt also:

    1. in "a* listeErweitern" gibt mir jedes Element für "naechsterEintrag" (und für "aInhalt")die Meldung:
      main.cpp:150:18: error: 'naechsterEintrag' is a private member of 'listenelement'
      main.cpp:135:20: note: implicitly declared private here

    2. Zum Test habe ich daher sowohl "naechsterEintrag" als auch "aInhalt" in der Klasse als public deklariert. So kriege ich zwar diese Fehlermeldung nicht mehr (soll so aber nicht sein), stattdessen meckert das Programm bei jedem "endeDerListe = endeDerListe ->anhaengen("2", endeDerListe );" in main(); mit der folgenden Meldung:
      main.cpp:188: Fehler: undefined reference to `a::listeErweitern(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, a*)'

    Füge hier einmal den ganzen Code ein, den ich nun habe (sorry für die Länge):

    #include <iostream>
    using namespace std;
    
    class a {
        string aInhalt;
        a* naechsterEintrag;
    public:
        void ersterEintrag(string inhalt);
        a* listeErweitern(string inhalt, a* endeDerListe);
        void listeAusgeben();
        void listeLoeschen();
    };
    
    void a::ersterEintrag(string inhalt) {
        aInhalt = inhalt;
        naechsterEintrag = nullptr;
    }
    // Element an Liste anhaengen - hier wird gemaeckert, dass
    // "naechsterEintrag" a private member ist, Fehler 1) oben.
    a* listeErweitern(string inhalt, a* endeDerListe) {
        naechsterEintrag = new a();
        if (endeDerListe) 
            endeDerListe->naechsterEintrag = naechsterEintrag;
        naechsterEintrag->aInhalt = inhalt;
        naechsterEintrag->naechsterEintrag = nullptr;
    
        return endeDerListe;
    }
    // Alle Elemente ausgeben
    void a::listeAusgeben() {
        cout << aInhalt << '\n';
        if (naechsterEintrag != nullptr) {
            naechsterEintrag->listeAusgeben();
        }
    }
    // Speicher freigeben
    void a::listeLoeschen() {
        if (naechsterEintrag != nullptr) {
            naechsterEintrag->listeLoeschen();
            delete(naechsterEintrag);
        }
    }
    
    int main () {
        // Zeiger auf Listenanfang und Ende
        a* anfangDerListe;
        a* endeDerListe;
        // Erster Eintrag
        anfangDerListe = new a();
        anfangDerListe->ersterEintrag("0");
        // Weitere anhaengen - hier bekomme ich die Fehlermeldung
        // von 2) oben
        endeDerListe = endeDerListe->listeErweitern("1", endeDerListe);
        endeDerListe = endeDerListe->listeErweitern("2", endeDerListe);
        endeDerListe = endeDerListe->listeErweitern("3", endeDerListe);
        endeDerListe = endeDerListe->listeErweitern("4", endeDerListe);
       
        // Liste ausgeben (hier sollte "anfangDerListe" nach wie vor auf
        // den Anfang der Liste zeigen)
        anfangDerListe->listeAusgeben();
    
        // Liste abbauen und freigeben
        anfangDerListe->listeLoeschen();
        delete(anfangDerListe);
    }
    

    Ich weiß auch den Rat zu schätzen, es über eine separate Klasse zu machen (würde ich auch gerne) aber das ist hier leider nicht gefordert - hier muss ich es bei der Klasse behalten und lediglich über den Zeiger, der auf das letzte Element gesetzt ist, neue Elemente einfügen können. Vielen Dank für eure Hilfe und Geduld! 🙂. Ich habe das Konzept zwar einigermaßen verstanden, aber fürchte ich kann es nicht vernünftig umsetzen.



  • @Masch sagte in Zeiger auf Ende einer Objektkette setzen:

    a* listeErweitern(string inhalt, a* endeDerListe)

    sollte auch so heissen:

    a* a::listeErweitern(string inhalt, a* endeDerListe)
    

    Dann können deine Variblen wieder private sein und alles ist gut, aber ich dachte das wüsstest du, wobei der erste fehler schon alles sagt.



  • @Masch sagte in Zeiger auf Ende einer Objektkette setzen:

    main.cpp:150:18: error: 'naechsterEintrag' is a private member of 'listenelement'

    Dann mach es doch einfach public:

    class a {
    public:
        string aInhalt;
        a* naechsterEintrag;
    public:
        void ersterEintrag(string inhalt);
        a* listeErweitern(string inhalt, a* endeDerListe);
        void listeAusgeben();
        void listeLoeschen();
    };
    

    Dein Design ist doch eh verhunzt, da kommt es auf ein public mehr oder weniger nicht mehr darauf an.



  • @Quiche-Lorraine sagte in Zeiger auf Ende einer Objektkette setzen:

    Dann mach es doch einfach public

    Wenn du das Problem nicht verstanden hast halte dich mit solchen unsinngen Empfehlungen zurück!



  • @Masch sagte in Zeiger auf Ende einer Objektkette setzen:

    a* listeErweitern(string inhalt, a* endeDerListe) {
    

    ist nicht die Memberfunktion, sondern eine weitere freie Funktion.

    a* a::listeErweitern(string inhalt, a* endeDerListe) {
    

    definiert eine Memberfunktion. Der zweite Parameter wird damit überflüssig und kann weg!



  • Da, das ist Copy&Paste:

    1>------ Build started: Project: codefun, Configuration: Debug x64 ------
    1>codefun.cpp
    1>C:\Users\Swordfish\source\repos\cpp-playground\codefun\codefun.cpp(21,5): error C2065: 'naechsterEintrag': undeclared identifier
    1>C:\Users\Swordfish\source\repos\cpp-playground\codefun\codefun.cpp(23,21): error C2248: 'a::naechsterEintrag': cannot access private member declared in class 'a'
    1>C:\Users\Swordfish\source\repos\cpp-playground\codefun\codefun.cpp(6): message : see declaration of 'a::naechsterEintrag'
    1>C:\Users\Swordfish\source\repos\cpp-playground\codefun\codefun.cpp(4): message : see declaration of 'a'
    1>C:\Users\Swordfish\source\repos\cpp-playground\codefun\codefun.cpp(23,42): error C2065: 'naechsterEintrag': undeclared identifier
    1>C:\Users\Swordfish\source\repos\cpp-playground\codefun\codefun.cpp(24,5): error C2065: 'naechsterEintrag': undeclared identifier
    1>C:\Users\Swordfish\source\repos\cpp-playground\codefun\codefun.cpp(25,5): error C2065: 'naechsterEintrag': undeclared identifier
    1>Done building project "codefun.vcxproj" -- FAILED.
    


  • Ahh nice, danke @CTecS und @manni66 - wusste nicht, dass ich das trotzdem mit a:: deklarieren muss, aber ergibt Sinn ...

    Jetzt habe ich das Private/Public Problem nicht mehr und es scheint zu laufen. Das einzige Problem ist nur, dass bei der Ausgabe nun nur das letzte Element erscheint und nicht die ganzen anderen, die ich vorher angehängt habe.

    Zwei Möglichkeiten mit denen ich experimentiere grade:

    1. in "int main();"(edited)
    // Bekomme die Meldung, dass "endeDerListe" hier nicht initialisiert ist
    // lege also fest:
        // Erster Eintrag
        anfangDerListe = new a();
        anfangDerListe->ersterEintrag("0");
        endeDerListe = anfangDerListe; //hier versucht, den Zeiger zu kopieren
        // Weitere anhaengen - hier bekomme ich die Fehlermeldung
        // von 2) oben
        endeDerListe = endeDerListe->listeErweitern("1", endeDerListe);
        endeDerListe = endeDerListe->listeErweitern("2", endeDerListe);
        endeDerListe = endeDerListe->listeErweitern("3", endeDerListe);
        endeDerListe = endeDerListe->listeErweitern("4", endeDerListe);
    
    // Das führt dazu, dass beide Zeiger die gleiche Adresse haben, somit
    // behaelt "anfangDerListe" nicht seinen Wert und übernimmt stets den
    // von "endeDerListe"
    
    1. endeDerListe nicht festlegen nach dem initialisieren, was mir leider gar keine Ausgaben liefert

    Habt ihr Ideen, wie ich "endeDerListe" vernünftig initialisieren / festlegen kann, damit nur "endeDerListe" weiterwandert und "anfangDerListe" auf dem ersten Element bleibt?

    Vielen Dank nochmal für eure Hilfe, hat mir bisher schon viel geholfen. Lieber Gruß.



  • @Masch sagte in Zeiger auf Ende einer Objektkette setzen:

    , endeDerListe)

    Warum existiert das noch?



  • @manni66 - ich hatte versucht den Parameter rauszunehmen, dann hatte ich aber ein Problem mit dem Return Value von "listeErweitern()". Wenn ich das Listenende nicht in den Parameter reinschleuse, was kann "listeErweitern()" dann zurückgeben um es "endeDerListe" in main zuzweisen?



  • @Masch sagte in Zeiger auf Ende einer Objektkette setzen:

    was kann "listeErweitern()" dann zurückgeben um es "endeDerListe" in main zuzweisen?

    naechsterEintrag, wie von @Schlangenmensch schon vor vier Stunden gezeigt?



  • @manni66 niiiiice! Sorry, die Befehle haben sich ein paarmal geändert - hab den Vorschlag von @Schlangenmensch übernommen (zusätzlich zu dem restlichen Skript von vorher) und läuft ... Hammerhart.

    Werde gleich meine Beschwerde einreichen, dass mir ineffektives Coding beigebracht wird und ich unzählige Stunden an der Lösung verschwendet habe (größtenteils leider wirklich wegen meines Fehlers mit "a* a::listeErweitern" <- das mit dem a::)

    Euch allen vielen vielen Dank für eure Hilfe, ihr habt mir viele weitere Stunden kniffelei und großes Kopfzerbrechen erspart. 🙏


Anmelden zum Antworten