C++ [Verkettete Liste] Ein Element über eine Funktion an die Liste anhängen

Dabei seit
Feb. 2018
Beiträge
154
N'Abend allerseits,

ich hocke gerade vor einem C++ Programm bei welchem ich eine verkettete Liste erstelle. Die verkettete Liste, bei der ich Elemente im Code definiere funktioniert, allerdings habe ich nun Probleme dabei meine Elemente selbst einzutragen.

Header:
C++:
#pragma once
#define NIL (cSchachfeld*)0
class cSchachfeld
{
private:
    int y;
    char x;

    cSchachfeld* prev;
public:
    cSchachfeld(char x_in, int y_in, cSchachfeld* prev_in);
    ~cSchachfeld();
    cSchachfeld* newEl(char x_in, int y_in);
    void print_list();
    friend cSchachfeld* laeuferzug(cSchachfeld*);
};

cSchachfeld.cpp
C++:
#include "cSchachfeld.h"
#include <iostream>
using namespace std;

cSchachfeld::cSchachfeld(char x_in, int y_in, cSchachfeld* prev_in) : x(x_in), y(y_in), prev(prev_in)
{
}

cSchachfeld::~cSchachfeld()
{
    if(prev != NIL)
        delete prev;
    cout << "delete: " << x << y << endl;
}

cSchachfeld* cSchachfeld::newEl(char x_in, int y_in)
{
    return new cSchachfeld(x_in, y_in, this);            // hiermit soll er sich selbst als vorgänger reinschreiben
}

void cSchachfeld::print_list()
{
    if (prev != NIL)
        prev->print_list();
    cout << "print: " << x << y << endl;
}

main.cpp
C++:
#include "cSchachfeld.h"
#include <iostream>
using namespace std;


/* X ist der Character und Y ist der Integer */



cSchachfeld* laeuferzug(cSchachfeld* old)
{
    char buchst;
    int zahl;

    cout << "Bitte geben Sie 2 Werte ein: ";
    cin >> buchst >> zahl;

    cSchachfeld* laeufer = old;
    laeufer->newEl(buchst, zahl);
   

    return laeufer;
}


int main() {

    cout << "\tProgramm zur Erstellung von Verketteten Listen\n" << endl;

    cSchachfeld* p_act = new cSchachfeld('E', 7, NIL);        // Erstes Element in der Liste

    p_act = p_act->newEl('F', 5);            // 2. Element in der Liste
    p_act = laeuferzug(p_act);                // 3. Element in der Liste

   
    p_act->print_list();

    delete p_act;
    return 0;
}


Mein Ziel ist es nun, über die Funktion laeuferzug() auszuführen. In der Funktion soll ein neues Element erstellen werden, welches entweder die Informationen des vorherigen Knoten übernimmt oder komplett leer ist, soll dann aber mit der Methode newEl() mit neuen Informationen (welcher vorher von cin in Hilfsvariablen eingelesen werden) eingetragen werden. Das Problem ist allerdings, das der Knoten nicht ans Ende angehängt wird..

Kann mir da jemand helfen?

Edit: Programm ist für die Uni, verwendet wird VS2019


MfG.
 
Zuletzt bearbeitet:

Fortatus

Lt. Commander
Dabei seit
Juni 2009
Beiträge
2.023
Zuvor vllt die Rückfrage: Wofür schreibst du das Programm? Uni oder Schule? Welchen Compiler benutzt ihr?
 

deep90sravioli

Ensign
Ersteller dieses Themas
Dabei seit
Feb. 2018
Beiträge
154
Zitat von Fortatus:
Zuvor vllt die Rückfrage: Wofür schreibst du das Programm? Uni oder Schule? Welchen Compiler benutzt ihr?

Sorry hab ich vor lauter Programmieren komplett verpeilt, läuft unter Windoof 10 mit VS2019. Programm ist für die Uni, muss also nicht an den Mann.


Hab die Funktion lauferzug() jetzt mal in eine Methode umgeschrieben, habe dort kein neues Objekt erzeugt sondern den Return direkt in new cSchachfeld(buchst, zahl, this); umgeschrieben. Mit dieser Methode funktioniert das erstellen von Kette nun, ich würde es aber gerne trotzdem mit einer Funktion aus der main versuchen, welche mit friend in die Klasse eingebunden wird. Funktioniert das dann so auch überhaupt?
 

Fortatus

Lt. Commander
Dabei seit
Juni 2009
Beiträge
2.023
Also entweder ich mache grade einen Denkfehler, oder:
  • die Funktion laeuferzug muss kein Friend der Klasse cSchachfeld sein. Du greifst nicht direkt auf private-Teile zu. laeuferzug() ist einfach nur ein Wrapper für das Ausführen von newEl.
  • Ob Friend oder Nicht-Friend: Die Zuweisung old->laeufer in laeuferzug kannst du dir sparen. Oder funktioniert
    "old->newEl(buchst, zahl);" und dann
    "return old;" nicht?
Sofern VS2019 und C++ die einzigen Vorgaben sind: Hast du dich schonmal mit unique_ptr, shared_ptr etc auseinander gesetzt? In Zeiten von C++17 noch C++ von 1998 zu lernen, finde ich immer schade.
 

hoerg

Cadet 4th Year
Dabei seit
Okt. 2002
Beiträge
79
In Zeile 32 von main.cpp weist du der Methode newEl() jeweils das neu erstellte Objekt zu, siehe
C:
p_act = p_act->newEl('F', 5); // 2. Element in der Liste


Innerhalb deiner Funktion laeuferzug fehlt diese Zuweisung
C:
laeufer->newEl(buchst, zahl);


Richtig wäre hier
C:
laeufer = laeufer->newEl(buchst, zahl);
 

Fortatus

Lt. Commander
Dabei seit
Juni 2009
Beiträge
2.023
Jap, und dass hab ich jetzt auch gesehen:
Noch kürzer wäre natürlich:
C++:
return laeufer->newEl(buchst,zahl);

Richtig zusammengedampft würde die Funktion also lauten:
C++:
cSchachfeld* laeuferzug(cSchachfeld* old)
{
    char buchst;
    int zahl;

    cout << "Bitte geben Sie 2 Werte ein: ";
    cin >> buchst >> zahl;

    return old->newEl(buchst, zahl);
}
 

mkossmann

Lt. Commander
Dabei seit
Dez. 2015
Beiträge
2.039
Eigentlich sollte man sich angewöhnen in modernem C++ für Listen std::list zu verwenden statt die Liste selbst zusammen zu frickeln. Aber das ist wohl nicht Intention dieser Übungsaufgabe.
 

deep90sravioli

Ensign
Ersteller dieses Themas
Dabei seit
Feb. 2018
Beiträge
154
Zitat von Fortatus:
Also entweder ich mache grade einen Denkfehler, oder:
  • die Funktion laeuferzug muss kein Friend der Klasse cSchachfeld sein. Du greifst nicht direkt auf private-Teile zu. laeuferzug() ist einfach nur ein Wrapper für das Ausführen von newEl.
  • Ob Friend oder Nicht-Friend: Die Zuweisung old->laeufer in laeuferzug kannst du dir sparen. Oder funktioniert
    "old->newEl(buchst, zahl);" und dann
    "return old;" nicht?
Sofern VS2019 und C++ die einzigen Vorgaben sind: Hast du dich schonmal mit unique_ptr, shared_ptr etc auseinander gesetzt? In Zeiten von C++17 noch C++ von 1998 zu lernen, finde ich immer schade.

Hi, ja die unique und smart Pointer hab ich mir schon angeguckt, allerdings will der Professor das wir die alte Art von Pointern benutzen um zu lernen, wie Fatal ein fehlerhafter Umgang mit diesen sein kann. :D

Zitat von hoerg:
In Zeile 32 von main.cpp weist du der Methode newEl() jeweils das neu erstellte Objekt zu, siehe
C:
p_act = p_act->newEl('F', 5); // 2. Element in der Liste


Innerhalb deiner Funktion laeuferzug fehlt diese Zuweisung
C:
laeufer->newEl(buchst, zahl);


Richtig wäre hier
C:
laeufer = laeufer->newEl(buchst, zahl);

Danke daran hab ich auch nicht gedacht! Ich werd den Code später nochmal ein bisschen umschreiben und werde es einfach mal weiter versuchen!


Zitat von mkossmann:
Eigentlich sollte man sich angewöhnen in modernem C++ für Listen std::list zu verwenden statt die Liste selbst zusammen zu frickeln. Aber das ist wohl nicht Intention dieser Übungsaufgabe.

Ja allerdings, da gebe ich dir Recht. Ich bin in C++ auch kein Freund der alten Pointer aber leider sind das die vorgaben vom Prof. Konnte natürlich keiner von euch wissen, aber wenn ich an meinen Projekten arbeite dann benutze ich auch lieber Listen, unique/smart Pointer und Vektoren anstelle von alten Arrays.


Zitat von Fortatus:
Jap, und dass hab ich jetzt auch gesehen:
Noch kürzer wäre natürlich:
C++:
return laeufer->newEl(buchst,zahl);

Richtig zusammengedampft würde die Funktion also lauten:
C++:
cSchachfeld* laeuferzug(cSchachfeld* old)
{
    char buchst;
    int zahl;

    cout << "Bitte geben Sie 2 Werte ein: ";
    cin >> buchst >> zahl;

    return old->newEl(buchst, zahl);
}

Auch nochmal dazu, in der Aufgabenstellung steht, das wir in der Funktion ein neues Objekt erstellen sollen welches dann die neuen Werte zugewiesen bekommt (konntest du jetzt natürlich nicht wissen da mein übermedeter Hintern an nichts mehr gedacht hat).

Also: in der Funktion ein neues Objekt erstellen und zurück geben. Es soll noch eine Fehlerüberprüfung in der Funktion stattfinden, da wird manche Felder des Schachbrett nicht betreten dürfen. Sollten wir allerdings doch per Eingabe auf diese Felder kommen, so soll der Wert nicht gespeichert werden (deswegen habe ich 'old' hochgegeben, damit ich in einem solchen Falle den alten Wert per return in der if zurückgeben kann). :D


Danke nochmal an alle für die Hilfe!
 

Ebrithil

Lieutenant
Dabei seit
Dez. 2014
Beiträge
767
Zitat von mkossmann:
Eigentlich sollte man sich angewöhnen in modernem C++ für Listen std::list zu verwenden statt die Liste selbst zusammen zu frickeln. Aber das ist wohl nicht Intention dieser Übungsaufgabe.
Wenn mans ganz genau nimmt, sollte man eigentlich niemals listen benutzen, da diese aus Performance Sicht, bis auf ganz wenige Anwendungsfälle, eigentlich immer langsamer sind als Arrays bzw std::vector.
 
  • Gefällt mir
Reaktionen: Fortatus
Top