C++ programmieren


  • Mod

    lexteks schrieb:

    schade dass das so ein Problem ist...k.A. habs mit code tab versucht will aber nicht funktionieren...hmm

    Zitier meinen Beitrag, dann siehst du, wie die Tags gesetzt werden.



  • So nun die überarbeitete Version:

    /* ##################################
    
    Der Getränkeautomat Version 6
    
    Mit Konstruktoren und Destruktoren
    
    ###################################*/
    
    #include <iostream>
    
    using namespace std;
    
    //die Klasse getraenke
    class getraenke
    {
        public:
        //die Attribute
        string getraenk[3];
        int anzahlFlaschen[3];
        int preisProFlasche;
    
        //die Methoden
        //Konstruktor
        getraenke(int anzahl1,int anzahl2,int anzahl3);
        //Destruktor
        ~getraenke();
    };
    
    getraenke::getraenke(int anzahl1,int anzahl2,int anzahl3)
    {
        //die Getraenke eintragen
        getraenk[0]="Limonade";
        getraenk[1]="Wasser";
        getraenk[2]="Bier";
        //die Anzahl festlegen
        anzahlFlaschen[0]=anzahl1;
        anzahlFlaschen[1]=anzahl2;
        anzahlFlaschen[2]=anzahl3;
    }
    
    getraenke::~getraenke()
    {
        cout<<"Eine Instanz der Klasse Getraenke wurde zerstört."<<endl;
    }
    
    //die Vereinbarung der Klasse muenzeinheit
    
    class muenzeinheit
    
    {
    
        //die Attribute
    
        int betrag;
    
        int nochZuZahlen;
    
        int rueckgeld;
    
        //die Methoden
    
        public:
    
        //der Konstruktor
    
        muenzeinheit();
    
        //der Destruktor
    
        ~muenzeinheit();
    
        void muenzenAnnehmen(int wert);
    
        int rueckgeldGeben();
    
        //zum Setzen des Betrags
    
        void setBetrag(int preis);
    
        //zum Abfragen des noch zu zahlenden Betrags
    
        int getnochZuZahlen();
    
    };
    
    muenzeinheit::muenzeinheit()
    
    {
    
        betrag = 0;
    
        nochZuZahlen = 0;
    
        rueckgeld = 0;
    
    }
    
    muenzeinheit::~muenzeinheit()
    
    {
    
        cout << "Eine Instanz der Klasse muenzeinheit wurde zerstoert." << endl;
    
    }
    
    void muenzeinheit::muenzenAnnehmen(int wert)
    
    {
    
        //den eingeworfenen Betrag abziehen
    
        nochZuZahlen = nochZuZahlen - wert;
    
    }
    
    int muenzeinheit::rueckgeldGeben()
    
    {
    
        //den absoluten Betrag von nochZuZahlen als Rückgeld liefern
    
        rueckgeld = abs(nochZuZahlen);
    
        return rueckgeld;
    
    }
    
    void muenzeinheit::setBetrag(int preis)
    
    {
    
        betrag = preis;
    
        nochZuZahlen = betrag;
    
    }
    
    int muenzeinheit::getnochZuZahlen()
    
    {
    
        return nochZuZahlen;
    
    }
    
    //die Vereinbarung der Klasse getraenkeautomat
    
    class getraenkeautomat
    
    {
    
        //die Attribute
    
        bool kuehlung;
    
        //jetzt ist die Münzeinheit Teil des Getränkeautomaten
    
        muenzeinheit *zahlomat;
        getraenke* getraenkomat;
    
        public:
    
        //die Methoden
    
        //der Konstruktor
    
        //übergeben werden drei int-Typen für die Anzahl und ein Zeiger auf die Klasse muenzeinheit
    
        getraenkeautomat(muenzeinheit *tempZahlomat,getraenke* tempgetraenkomat);
    
        //der Destruktor
    
        ~getraenkeautomat();
    
        int getraenkeWaehlen();
    
        void getraenkAusgeben(int anzahl, int getraenkeIndex);
    
        void kuehlen(bool anaus);
    
    };
    
    getraenkeautomat::getraenkeautomat(muenzeinheit *tempZahlomat,getraenke* tempgetraenkomat)
    
    {
    
        //die Kühlung ist aus
    
        kuehlung = false;
    
        //die Instanz der Münzeinheit wird zugewiesen
    
        zahlomat = tempZahlomat;
        getraenkomat=tempgetraenkomat;
    }
    
    getraenkeautomat::~getraenkeautomat()
    
    {
    
        cout << "Eine Instanz der Klasse getraenkeautomat wurde zerstoert." << endl;
    
    }
    
    int getraenkeautomat::getraenkeWaehlen()
    
    {
    
        int auswahl, anzahl;
    
        //die Auswahl
    
        cout << "Bitte waehlen Sie ein Getraenk: " << endl;
    
        cout << "Es gibt folgende Auswahl: " << endl;
    
        for (int index = 0; index < 3; index++)
    
            cout << index+1 << " - " << getraenkomat->getraenk[index] << endl;
    
        cout << "Geben Sie die gewuenschte Nummer ein: ";
    
        cin >> auswahl;
    
        //gibt es noch Flaschen vom gewählten Getränk?
    
        if (getraenkomat->anzahlFlaschen[auswahl-1] != 0)
    
        {
    
            //das Getränk ausgeben
    
            cout << "Wie viele Flaschen moechten Sie? ";
    
            cin >> anzahl;
    
            //erst muss bezahlt werden
    
            //der Preis 10 ist fest vorgegeben
    
            cout << "Sie muessen " << anzahl * 10 << " Cent bezahlen." << endl;
    
            zahlomat->setBetrag(anzahl * 10);
    
            do {
    
                cout << "Es fehlen noch " << zahlomat->getnochZuZahlen() << " Cent." << endl;
    
                zahlomat->muenzenAnnehmen(3);
    
            } while (zahlomat->getnochZuZahlen() >0);
    
            //das Getränk ausgeben
    
            auswahl = auswahl - 1;
    
            getraenkAusgeben(anzahl, auswahl);
    
        }
    
        else
    
        {
    
            cout << "Das gewaehlte Getraenk ist leider nicht mehr vorhanden." << endl;
    
            auswahl = -1;
    
        }
    
        return auswahl;
    
    }
    
    void getraenkeautomat::getraenkAusgeben(int anzahl, int getraenkeIndex)
    
    {
    
        //gibt es noch genügend Flaschen?
    
        if (anzahl <= getraenkomat->anzahlFlaschen[getraenkeIndex])
    
        {
    
            cout << "Sie erhalten " << anzahl << " Flasche(n) " << getraenkomat->getraenk[getraenkeIndex] << endl;
    
            getraenkomat->anzahlFlaschen[getraenkeIndex] = getraenkomat->anzahlFlaschen[getraenkeIndex]  - anzahl;
    
        }
    
        else
    
        {
    
            cout << "Es sind nur noch " << getraenkomat->anzahlFlaschen[getraenkeIndex] << " Flasche(n) " << getraenkomat->getraenk[getraenkeIndex] << " vorhanden. ";
    
            cout << "Sie erhalten den Rest." << endl;
    
            getraenkomat->anzahlFlaschen[getraenkeIndex] = 0;
    
        }
    
        //Geld zurückgeben
    
        cout << "Sie erhalten " << zahlomat->rueckgeldGeben() << " Cent zurueck." << endl;
    
    }
    
    void getraenkeautomat::kuehlen(bool anaus)
    
    {
    
        if (anaus == true)
    
        {
    
            kuehlung = true;
    
            cout << "Die Kuehlung ist eingeschaltet. " << endl;
    
        }
    
        else
    
        {
    
            kuehlung = false;
    
            cout << "Die Kuehlung ist ausgeschaltet. " << endl;
    
        }
    
    }
    
    int main()
    
    {
    
        int auswahl;
    
        //Instanz erzeugen
    
        //der Zeiger auf die Klasse
    
        getraenkeautomat *automat;
    
        //die Münzeinheit erzeugen
    
        muenzeinheit *einheit = new muenzeinheit();
    
        //die Münzeinheit wird jetzt übergeben
    
        automat = new getraenkeautomat(10, 20, 30, einheit);
    
        //ein Getränk auswählen
    
        do {
    
            auswahl = automat->getraenkeWaehlen();
    
        } while (auswahl == -1);
    
        //die Instanzen freigeben
    
        delete(automat);
    
        return 0;
    
    }
    

    Problem ist das die meldung in Zeile 405 kommt:
    error: no matching function for call to `getraenkeautomat::getraenkeautomat(int, int, int, muenzeinheit*&)'|

    Bitte um dringenden Rat...



  • Es gibt hier nur einen Konstruktor:

    getraenkeautomat::getraenkeautomat(muenzeinheit *tempZahlomat,getraenke* tempgetraenkomat)
    

    Und du versuchst einen Konstruktor zu nutzen, den es nicht gibt.



  • out schrieb:

    Es gibt hier nur einen Konstruktor:

    Nein, es gibt zwei, um ganz genau zu sein. 🤡



  • Sone schrieb:

    out schrieb:

    Es gibt hier nur einen Konstruktor:

    Nein, es gibt zwei, um ganz genau zu sein.

    Also meiner Meinung nach gibt es drei Konstruktoren und zwar in jeder Klasse einen,getraenke,getraenkeautomat und muenzeinheit. nur wie bekomme ich die Attribute aus der Klasse getraenke im zusammenspiel in die main funktion??



  • Nein, ich meinte, die Klasse getraenkeautomat hat zwei Konstruktoren.



  • out hat die Frage an sich schon beantwortet.
    Du benutzt einen Konstruktor, der nicht (mehr?) da ist.

    Betrachte folgenden Link: http://www.c-plusplus.net/forum/304133

    Besonders z. Thema "Den Code reduzieren" niemand hat Lust sich 400+ Zeilen durchzuschauen.

    Vereinfacht stellt sich Dein Problem so dar:

    struct muenzeinheit {};
    
    struct getraenke{
      getraenke(int,int,int)
      {
      }
    };
    
    struct getraenkeautomat{
      getraenkeautomat(muenzeinheit*, getraenke*)
      {
      }
    };
    
    int main(){
      muenzeinheit* einheit = new muenzeinheit;
      getraenkeautomat* automat = new getraenkeautomat(10, 20, 30, einheit);
      delete automat;
      delete einheit;
    }
    

    Siehst du jetzt, warum der Compiler das nicht übersetzen kann?

    Ich nehme an Du hattest mal eine Version, in der Du die Getraenke als einzelne ints (10, 20, 30) übergeben hast und hast das refaktoriert.



  • Sone schrieb:

    Nein, ich meinte, die Klasse getraenkeautomat hat zwei Konstruktoren.

    Zeig 😕



  • Ach du meinst den Kopierkonstruktor.



  • aber ich bin blutiger Anfänger,wenn ihr ein bisschen konkreter werden würdet wäre das echt hilfreich.Danke :))



  • wenn ich das richtig sehe sind die Klassen alle richtig deklariert und auch alle vernünftig miteinander verbunden,Problem liegt in der Main Funktion.
    wie kann ich die Attribute der klasse getraenke über den Konstruktor für die methoden der klasse getraenkeautomat einbinden???



  • falls jemand das ergebniss interessiert:

    /* ##################################
    
    Der Getränkeautomat Version 6
    
    Mit Konstruktoren und Destruktoren
    
    ###################################*/
    
    #include <iostream>
    
    using namespace std;
    
    //die Klasse getraenke
    class getraenke
    {
        public:
        //die Attribute
        string getraenk[3];
        int anzahlFlaschen[3];
        int preisProFlasche;
    
        //die Methoden
        //Konstruktor
        getraenke(int anzahl1,int anzahl2,int anzahl3);
        //Destruktor
        ~getraenke();
    };
    
    getraenke::getraenke(int anzahl1,int anzahl2,int anzahl3)
    {
        //die Getraenke eintragen
        getraenk[0]="Limonade";
        getraenk[1]="Wasser";
        getraenk[2]="Bier";
        //die Anzahl festlegen
        anzahlFlaschen[0]=anzahl1;
        anzahlFlaschen[1]=anzahl2;
        anzahlFlaschen[2]=anzahl3;
    }
    
    getraenke::~getraenke()
    {
        cout<<"Eine Instanz der Klasse Getraenke wurde zerstört."<<endl;
    }
    
    //die Vereinbarung der Klasse muenzeinheit
    
    class muenzeinheit
    
    {
    
        //die Attribute
    
        int betrag;
    
        int nochZuZahlen;
    
        int rueckgeld;
    
        //die Methoden
    
        public:
    
        //der Konstruktor
    
        muenzeinheit();
    
        //der Destruktor
    
        ~muenzeinheit();
    
        void muenzenAnnehmen(int wert);
    
        int rueckgeldGeben();
    
        //zum Setzen des Betrags
    
        void setBetrag(int preis);
    
        //zum Abfragen des noch zu zahlenden Betrags
    
        int getnochZuZahlen();
    
    };
    
    muenzeinheit::muenzeinheit()
    
    {
    
        betrag = 0;
    
        nochZuZahlen = 0;
    
        rueckgeld = 0;
    
    }
    
    muenzeinheit::~muenzeinheit()
    
    {
    
        cout << "Eine Instanz der Klasse muenzeinheit wurde zerstoert." << endl;
    
    }
    
    void muenzeinheit::muenzenAnnehmen(int wert)
    
    {
    
        //den eingeworfenen Betrag abziehen
    
        nochZuZahlen = nochZuZahlen - wert;
    
    }
    
    int muenzeinheit::rueckgeldGeben()
    
    {
    
        //den absoluten Betrag von nochZuZahlen als Rückgeld liefern
    
        rueckgeld = abs(nochZuZahlen);
    
        return rueckgeld;
    
    }
    
    void muenzeinheit::setBetrag(int preis)
    
    {
    
        betrag = preis;
    
        nochZuZahlen = betrag;
    
    }
    
    int muenzeinheit::getnochZuZahlen()
    
    {
    
        return nochZuZahlen;
    
    }
    
    //die Vereinbarung der Klasse getraenkeautomat
    
    class getraenkeautomat
    
    {
    
        //die Attribute
    
        bool kuehlung;
    
        //jetzt ist die Münzeinheit Teil des Getränkeautomaten
    
        muenzeinheit *zahlomat;
        getraenke* getraenkomat;
    
        public:
    
        //die Methoden
    
        //der Konstruktor
    
        //übergeben werden drei int-Typen für die Anzahl und ein Zeiger auf die Klasse muenzeinheit
    
        getraenkeautomat(muenzeinheit *tempZahlomat,getraenke* tempgetraenkomat);
    
        //der Destruktor
    
        ~getraenkeautomat();
    
        int getraenkeWaehlen();
    
        void getraenkAusgeben(int anzahl, int getraenkeIndex);
    
        void kuehlen(bool anaus);
    
    };
    
    getraenkeautomat::getraenkeautomat(muenzeinheit *tempZahlomat,getraenke* tempgetraenkomat)
    
    {
    
        //die Kühlung ist aus
    
        kuehlung = false;
    
        //die Instanz der Münzeinheit wird zugewiesen
    
        zahlomat = tempZahlomat;
        getraenkomat = tempgetraenkomat;
    }
    
    getraenkeautomat::~getraenkeautomat()
    
    {
    
        cout << "Eine Instanz der Klasse getraenkeautomat wurde zerstoert." << endl;
    
    }
    
    int getraenkeautomat::getraenkeWaehlen()
    
    {
    
        int auswahl, anzahl;
    
        //die Auswahl
    
        cout << "Bitte waehlen Sie ein Getraenk: " << endl;
    
        cout << "Es gibt folgende Auswahl: " << endl;
    
        for (int index = 0; index < 3; index++)
    
            cout << index+1 << " - " << getraenkomat->getraenk[index] << endl;
    
        cout << "Geben Sie die gewuenschte Nummer ein: ";
    
        cin >> auswahl;
    
        //gibt es noch Flaschen vom gewählten Getränk?
    
        if (getraenkomat->anzahlFlaschen[auswahl-1] != 0)
    
        {
    
            //das Getränk ausgeben
    
            cout << "Wie viele Flaschen moechten Sie? ";
    
            cin >> anzahl;
    
            //erst muss bezahlt werden
    
            //der Preis 10 ist fest vorgegeben
    
            cout << "Sie muessen " << anzahl * 10 << " Cent bezahlen." << endl;
    
            zahlomat->setBetrag(anzahl * 10);
    
            do {
    
                cout << "Es fehlen noch " << zahlomat->getnochZuZahlen() << " Cent." << endl;
    
                zahlomat->muenzenAnnehmen(3);
    
            } while (zahlomat->getnochZuZahlen() >0);
    
            //das Getränk ausgeben
    
            auswahl = auswahl - 1;
    
            getraenkAusgeben(anzahl, auswahl);
    
        }
    
        else
    
        {
    
            cout << "Das gewaehlte Getraenk ist leider nicht mehr vorhanden." << endl;
    
            auswahl = -1;
    
        }
    
        return auswahl;
    
    }
    
    void getraenkeautomat::getraenkAusgeben(int anzahl, int getraenkeIndex)
    
    {
    
        //gibt es noch genügend Flaschen?
    
        if (anzahl <= getraenkomat->anzahlFlaschen[getraenkeIndex])
    
        {
    
            cout << "Sie erhalten " << anzahl << " Flasche(n) " << getraenkomat->getraenk[getraenkeIndex] << endl;
    
            getraenkomat->anzahlFlaschen[getraenkeIndex] = getraenkomat->anzahlFlaschen[getraenkeIndex]  - anzahl;
    
        }
    
        else
    
        {
    
            cout << "Es sind nur noch " << getraenkomat->anzahlFlaschen[getraenkeIndex] << " Flasche(n) " << getraenkomat->getraenk[getraenkeIndex] << " vorhanden. ";
    
            cout << "Sie erhalten den Rest." << endl;
    
            getraenkomat->anzahlFlaschen[getraenkeIndex] = 0;
    
        }
    
        //Geld zurückgeben
    
        cout << "Sie erhalten " << zahlomat->rueckgeldGeben() << " Cent zurueck." << endl;
    
    }
    
    void getraenkeautomat::kuehlen(bool anaus)
    
    {
    
        if (anaus == true)
    
        {
    
            kuehlung = true;
    
            cout << "Die Kuehlung ist eingeschaltet. " << endl;
    
        }
    
        else
    
        {
    
            kuehlung = false;
    
            cout << "Die Kuehlung ist ausgeschaltet. " << endl;
    
        }
    
    }
    
    int main()
    
    {
    
        int auswahl;
    
        //Instanz erzeugen
    
        //der Zeiger auf die Klasse
    
        getraenkeautomat *automat;
    
        //die Münzeinheit erzeugen
        getraenke *getraenkomat1 = new getraenke(10,20,30);
        muenzeinheit *einheit = new muenzeinheit();
    
        //die Münzeinheit wird jetzt übergeben
    
        automat = new getraenkeautomat(einheit,getraenkomat1);
    
        //ein Getränk auswählen
    
        do {
    
            auswahl = automat->getraenkeWaehlen();
    
        } while (auswahl == -1);
    
        //die Instanzen freigeben
    
        delete(automat);
    
        return 0;
    
    }
    

  • Mod

    new und delete braucht man eigentlich recht selten und ganz bestimmt nicht, wenn wie hier die Lebensdauer der Objekte mit dem der Pointer identisch ist. Du machst es auch prompt falsch und hast dir ein paar Speicherlöcher eingefangen. Lass es einfach weg.

    Noch ein paar Anmerkungen:

    Furble Wurble schrieb:

    Betrachte folgenden Link: http://www.c-plusplus.net/forum/304133

    Besonders z. Thema "Den Code reduzieren" niemand hat Lust sich 400+ Zeilen durchzuschauen.

    QFT.

    Man kann es mit Leerzeilen auch übertreiben. Wenn man (fast) überall Leerzeilen setzt, dann geht der trennende Effekt der Leerzeilen verloren.

    cstdlib für abs fehlt.

    So viel zum technischen und zur Form. Ich habe ja schon beschrieben, dass die Klassen nicht gut designed sind und klarer definierte Einsatzgebiete benötigen. Und habe dabei auch vorhergesagt, dass man sich so nur selber Probleme macht, was dann auch prompt eingetreten ist.

    Bau deine Klassen so auf, wie die echte Welt. Begriffe, die die Zusammenhänge zwischen Echtweltobjekten beschreiben, lassen sich oft direkt in C++ übersetzen:
    "hat ein" -> Member
    "ist eine Ansammlung von X" -> container<X>
    "ist ein" -> public-Vererbung
    "kann X tun" -> Memberfunktion
    "kann man X mit tun" -> freie Funktion



  • SeppJ schrieb:

    Man kann es mit Leerzeilen auch übertreiben. Wenn man (fast) überall Leerzeilen setzt, dann geht der trennende Effekt der Leerzeilen verloren.

    Habe ich auch gedacht, aber vielleicht ist das eine Eigenschaft des Editors der IDE, dass er die Zeilen durch CR+LF abschließt und das Forum daraus eine Leerzeile bastelt?
    Aber auf jeden Fall sollte TE das dann manuell korrigieren.


  • Mod

    Manchmal folgen aber auch mal zwei Zeilen aufeinander.


Anmelden zum Antworten