Auf einen Vektor einer anderen Klasse zugreifen



  • Hallo zusammen,

    irgendwie stehe ich etwas auf dem Schlauch und komme nicht weiter. Ich möchte gerne von der Klasse Ticketverwaltung auf den Vektor

    vector<Kinoprogramm *> kp
    

    in der Klasse Programmverwaltung zugreifen. Dies habe ich mit dem folgendem Code versucht aber bekomme dabei ein "segmentation fault 11" sprich irgendeine Verletzung des Speichers.

    void Ticketverwaltung::ticketKaufen()
    { 
       Programmverwaltung pv;
       //Programmverwaltung * pv; 
       cout << "Für welchen Film möchten Sie eine Karte kaufen?" << endl;
       pv->zeigeFilmSaal();
    }
    
    void Programmverwaltung::zeigeFilmSaal() {
     for (int i = 0; i < kp.size(); i++) {
    cout << "Titel: " << kp[i]->GetTitel() << ", Saal: " << kp[i]->GetKino() << endl;
    }
    }
    

    Danke schon mal Voraus!

    Viele Grüße
    SliceOfLife


  • Mod

    Segmentation fault deutet darauf hin, dass etwas mit Zeigern falsch gemacht wurde. Und da fällt direkt auf, dass du in deinem Vector rohe Zeiger gespeichert hast, was eher ungewöhnlich ist (eigentlich höchstens bei Polymorphie, deren Einsatzzweck ich hier aber nicht erkennen kann). Aber ohne, dass du erklärst, warum du das für richtig hältst oder ein vernünftiges Codebeispiel zeigst, kann man mehr dazu auch nicht sagen. Dein jetziges Codebeispiel ist jedenfalls unbrauchbar, da nicht erkennbar ist, was die Bezeichner sein sollen, wie der Programmfluss ist oder was der Code überhaupt mit deinem Beitrag zu tun hat. Mindestens der Konstruktor der Programmverwaltung ist hier nötig, weil da ja anscheinend das Befüllen von kp vonstatten geht.

    Wobei das Design, dass eine Programmverwaltung eine lokale Variable in einer Ticketverwaltung sein soll, irgendwie komisch aussieht. Was sollen diese beiden Klassen überhaupt darstellen? Woher kennt Ticketverwaltung::ticketKaufen das Kinoprogramm? Und wieso erzeugt es das Programm erst? Irgendwas passt da nicht.

    Dein auskommentiertes

    //Programmverwaltung * pv;
    

    sieht auch komisch aus, sehr nach Java. Versuch nicht Java in C++ zu machen. In C++ braucht nicht alles ein Zeiger zu sein und wenn man doch mal Zeiger hat, sieht man sie nicht (z.B. die internen Zeiger in std::vector).

    Der Fehler ist wahrscheinlich auf eine der folgenden Ursachen oder ein Kombination davon zurück zu führen:
    -Technisch falscher Umgang mit Zeigern
    -Unnötige Benutzung von Zeigern
    -Klassen und Funktionen haben keine klaren Aufgaben und das Verhältnis verschiedener Klassen ist unklar
    -Technisch falsche Umsetzung der Aufgaben der Klassen und Funktionen (z.B. welche Objekte wo leben und wie miteinander kommunizieren)



  • Das komplette Programm soll eine rudimentäre Kinosoftware sein mit Konsolenausgabe. Die Idee war, dass Ticketverwaltung und Programmverwaltung jeweils die "Control-Klassen" sind, die die Objekte erstellen und in den Vektoren speichern.

    Ticketverwaltung zeigt dabei auf die "Entity-Klassen" Platz und Ticket, erstellt dann nach bedarf die entsprechenden Objekte und speichert diese in den Vektoren:
    vector<Ticket *> ti
    vector<Platz *> pl

    Programmverwaltung zeigt auf die "Entity-Klassen" Film, Kinoprogramm und Vorstellung, erstellt dann auch wieder nach bedarf die Objekte und speichert diese in den Vektoren:
    vector<Film *> fi
    vector<Kinoprogramm > kp
    vector<Vorstellung
    > vs

    Hier ein Beispiel mit Kinoprogramm:

    //Konstruktor Kinoprogramm
    Kinoprogramm(string v_kw, string v_tag, string v_uhrzeit, string v_titel, string v_kategorie, string v_laenge, int v_kino);
    
    //Objekt wird in Programmverwaltung erstellt
    for (int i = 0; i < fi.size(); i++) {
            Kinoprogramm * k = new Kinoprogramm(kw, vs[i]->GetTag(), vs[i]->GetUhrzeit(), fi[i]->getFilmtitel(), film.getKategorie(fi[i]->getFilmkategorie()), fi[i]->getFilmlaenge(), vs[i]->GetKino());
            kp.push_back(k);
        }
    

    Kinoprogramm zieht sich also aus dem Filmvektor und Vorstellungsvektor die entsprechenden Daten und erstellt dann das Kinoprogrammobjekt.

    Um dann von Ticketverwaltung auf eine Methode von Programmverwaltung zuzugreifen, habe ich dann einfach nur die Klasse Programmverwaltung includiert und versucht aus Ticketverwaltung die Methode zeigeFilmSaal mit "Programmverwaltung pv" aufzurufen, um mir die entsprechenden Filme im jeweiligen Saal anzeigen zu lassen.

    void Ticketverwaltung::ticketKaufen() 
    { 
       Programmverwaltung pv; 
       cout << "Für welchen Film möchten Sie eine Karte kaufen?" << endl; 
       pv->zeigeFilmSaal(); 
    } 
    
    void Programmverwaltung::zeigeFilmSaal() { 
     for (int i = 0; i < kp.size(); i++) { 
    cout << "Titel: " << kp[i]->GetTitel() << ", Saal: " << kp[i]->GetKino() << endl; 
    } 
    }
    

    Wenn ich die Methode "zeigeFilmSaal" in Programmverwaltung aufrufe funktioniert alles ohne Probleme und bekomme die entsprechenden Daten angezeigt, aber sobald ich den Umweg über Ticketverwaltung wähle mit "pv." bekomme ich den erwähnten Fehler.



  • Wieso nutzt du Pointer? Speichere die Objekte doch einfach so im Vektor.



  • In einem solchen Programm ist es natürlich egal ob man Zeiger nimmt oder es lässt. War einfach eine intuitive Entscheidung. Habe es jetzt auch noch mal komplett umgestellt und arbeite ohne Zeiger aber trotzdem kommt der Fehler "Segmentation fault" wenn ich wie beschrieben auf die Methode zugreifen und etwas aus dem Vektor lesen möchte. Wie könnte ich denn sonst von der Klasse Ticketverwaltung aus auf den Vektor von Programmverwaltung zugreifen?

    //Aufruf zum Test in der main
    Programmverwaltung verwaltung;
    Ticketverwaltung ticket;
    
    ticket.ticketKaufen(); //Fehlermeldung
    verwaltung.zeigeFilmSaal(); // Gibt mir die Daten aus
    


  • SliceOfLife schrieb:

    In einem solchen Programm ist es natürlich egal ob man Zeiger nimmt oder es lässt.

    Abgesehen davon, dass mit Code dein Code deutlich langsamer, fehleranfälliger, nicht exception safe, komplexer, schlechter wartbarer und allgemein schlechter wird, ist es egal, ja.

    //Aufruf zum Test in der main
    Programmverwaltung verwaltung;
    Ticketverwaltung ticket;
    
    ticket.ticketKaufen(); //Fehlermeldung
    verwaltung.zeigeFilmSaal(); // Gibt mir die Daten aus
    

    Woher soll dein ticket-Objekt von deinem verwaltungs-Objekt wissen?



  • Wie mache ich dann dies bekannt? Dachte ein include in der Ticketverwaltungsklasse reicht aus.

    #include "Programmverwaltung.h"
    


  • Nein, das alleine reicht sicherlich nicht.
    Du mußt eine Beziehung zwischen den beiden Objekten herstellen, z.B. als Konstruktorparameter oder Methodenparameter übergeben.



  • Th69 schrieb:

    Nein, das alleine reicht sicherlich nicht.
    Du mußt eine Beziehung zwischen den beiden Objekten herstellen, z.B. als Konstruktorparameter oder Methodenparameter übergeben.

    Und in diesem Fall bräuchtest du ggf. auch einen Pointer. Aber kein new.



  • SliceOfLife schrieb:

    Wie könnte ich denn sonst von der Klasse Ticketverwaltung aus auf den Vektor von Programmverwaltung zugreifen?

    Gar nicht. Du rufst ja auch eine Memberfunktion auf, die dies dann macht.

    Allerdings scheint dir der Unterschied zwischen Klasse und Objekt/Instanz nicht klar zu sein. In deinem Beispiel benutzt ticket.ticketKaufen() eine andere Paketverwaltung, als die Namens "verwaltung" in der main-Funktion.

    Was du in deiner Funktion ticketKaufen falsch machst kann dir keiner sagen. Der hier gezeigte Code ist nicht der, der bei dir abstürzt, da er nicht übersetzbar ist!



  • SliceOfLife schrieb:

    Kinoprogramm(string v_kw, string v_tag, string v_uhrzeit, string v_titel, string v_kategorie, string v_laenge, int v_kino);
    

    Was sollen diese ganzen v_ Präfixe? Bei Parametern braucht man echt keine Präfixe.

    Wo passiert der Segmentation Fault? In ticketKaufen? Der Code wie du ihn zuletzt gepostet hast, kann nicht funktionieren.

    Programmverwaltung pv;

    Und dann

    pv->zeigeFilmSaal();

    Das passt nicht zusammen. Entweder ist es ein Zeiger, oder kein Zeiger. Und wenns einer ist, hast du ihn vielleicht nicht richtig initialisiert.



  • Als der Vektor noch mit Zeiger war habe ich mit "->" darauf zugegriffen und nun ohne Zeiger mit ".".

    Ich verstehe einfach nicht wo das Problem ist 😞 . Hier mal meine Gedankengänge:
    In der Methode ticketKaufen() die in der Klasse Ticketverwaltung ist, erstelle ich ein Objekt vom Typ Programmverwaltung (Programmverwaltung pv). Mit diesem Objekt möchte ich nun die Methode zeigeFilmSaal() aus der Klasse Programmverwaltung aufrufen (pv.zeigeFilmSaal()). Das Objekt hat doch zugriff auf den Vektor und kann mir doch theoretisch den gewünschten Wert zurückgeben oder nicht?

    void Ticketverwaltung::ticketKaufen() 
    { 
       Programmverwaltung pv; 
       cout << "Für welchen Film möchten Sie eine Karte kaufen?" << endl; 
       pv.zeigeFilmSaal(); 
    } 
    
    void Programmverwaltung::zeigeFilmSaal() { 
     for (int i = 0; i < kp.size(); i++) { 
    cout << "Titel: " << kp[i]->GetTitel() << ", Saal: " << kp[i]->GetKino() << endl; 
    } 
    }
    

    Der Fehler kommt sobald ich versuche über pv.zeigeFilmSaal() auf den Vektor zuzugreifen.



  • SliceOfLife schrieb:

    Als der Vektor noch mit Zeiger war habe ich mit "->" darauf zugegriffen und nun ohne Zeiger mit ".".

    Und was ist sonst im echten Code noch anders?

    SliceOfLife schrieb:

    Das Objekt hat doch zugriff auf den Vektor

    Auf seinen Vector.



  • SliceOfLife schrieb:

    Ich verstehe einfach nicht wo das Problem ist 😞 .

    Für sowas gibt es Debugger. Der fängt die Exception und dann siehst du im Callstack, was passiert ist.


Anmelden zum Antworten