Permalänk

C++ bank med två klasser

Har fastnat i en uppgift där jag ska skapa ett banksystem där man kan skapa konto och skriva in uppgifter. Så här ser uppgiften ut: Skapa klasserna KONTO och BANK. KONTO har attributen nummer, innehavare, saldo, rantesats, samt metoderna konto (konstruktor), skrivut, ge_nummer, ranteutbetalning (till alla konto). Klassen BANK har attributen konto (vektor eller array), antal konto, med metoderna bank (konstruktor), skriv_kontolista, nytt_konto, ranteutbetalning, sok_kontonr.

Jag får ihop ett fullt fungerande program om jag bara utgår från en enda klass. Men jag är helt handfallen på hur jag gör när det är två klasser inblandade. Jag förstår inte hur jag ska få den ena klassen att fungera tillsammans med den andra klassen. Här är lite vad jag skrivit. Om man väljer att se konto så kraschar programmet och jag vet inte varför.

#include <iostream> #include <vector> using namespace std; class Konto { public: int nummer; string innehavare; float saldo; float rantesats; Konto() { //KONSTRUKTUR ANGER DEFAULTVÄRDE SOM VISAS OM INGET ANNAT VÄRDE HAR ANGETTS. VÄLDIGT BRA FÖR ATT UNDVIKA ATT PROGRAMMET VISAR SKRÄPVÄRDEN. nummer=0; innehavare="KONTO EJ \x94PPNAT"; saldo=0.0; rantesats=0.0; } void setinfo(int _nummer, string _innehavare, float _saldo, float _rantesats) { nummer=_nummer; innehavare=_innehavare; saldo=_saldo; rantesats=_rantesats; } int ge_nummer() { //METOD SOM RETUNERAR KONTONUMMER return nummer; } int ranteutbetalning() { //METOD FÖR RÄNTA return (rantesats/100)*saldo; } }; class Bank : public Konto { public: int antal_konton; bank(){ antal_konton=0;} std::vector<Konto>konton; void setinfo(std::vector<Konto> _konton, int _antal_konton) { konton = _konton; antal_konton=_antal_konton; } int nytt_konto() { cout << endl << "Skriv kontonummer: "; cin >> nummer; cout << "Skriv namn: "; cin.ignore(); //RENSAR I PRINCIP CIN SÅ ATT GETLINE FUNKAR getline(cin, innehavare); // SUPERBRA DÅ DEN TAR MED ALLT MAN SKRIVER. ÄVEN MELLANRUM. KAN ALLTSÅ SKRIVA FÖR OCH EFTERNAMN cout << "Skriv in saldo: "; cin >> saldo; cout << "Skriv in % r\x84nta: "; cin >> rantesats; cout << endl; // konton.push_back(Konto(nummer, innehavare, saldo, rantesats)); } void skriv_kontolista() { for(int i=0; i<1; i++){ cout << endl << "Namn: " << konton[i].innehavare << endl; cout << "Kontonummer: " << konton[i].ge_nummer() << endl; //Text och anropade variabler skrivs ut i metoden. Metoden tillkallas sen i main. cout << "Saldo: " << konton[i].saldo << " kr" << endl; cout << "R\x84nta: " << konton[i].rantesats << " kr" << endl << endl;} } }; int main() { Konto konto; Bank bank; while(true) { //MENY LOOP int val; cout << "1. Nytt konto" << endl; cout << "2. Visa konto: " << endl; cout << "3. Ranteutbetalning: " << endl; cin >> val; switch(val) { //SWITCH BÄTTRE ÄN IF VID MENYVAL TYCKER JOCKE case 1: bank.nytt_konto(); break; case 2: bank.skriv_kontolista(); break; case 3: konto.ranteutbetalning(); break; } } return 0; }

Och så här ser mitt fungerande program ut, fast med bara en klass.

#include <iostream> using namespace std; class Konto { //SKAPAR KLASS FÖR KONTO public: string innehavare; int knummer; double saldo; double rantesats; Konto() { //KONSTRUKTUR ANGER DEFAULTVÄRDE SOM VISAS OM INGET ANNAT VÄRDE HAR ANGETTS. VÄLDIGT BRA FÖR ATT UNDVIKA ATT PROGRAMMET VISAR SKRÄPVÄRDEN. knummer=0; innehavare="KONTO EJ \x94PPNAT"; saldo=0.0; rantesats=0.0; } void NyttKonto() { //METOD FÖR ATT SKAPA NYTT KONTO cout << endl << "Skriv kontonummer: "; cin >> knummer; cout << "Skriv namn: "; cin.ignore(); //RENSAR I PRINCIP CIN SÅ ATT GETLINE FUNKAR getline(cin, innehavare); // SUPERBRA DÅ DEN TAR MED ALLT MAN SKRIVER. ÄVEN MELLANRUM. KAN ALLTSÅ SKRIVA FÖR OCH EFTERNAMN cout << "Skriv in saldo: "; cin >> saldo; cout << "Skriv in % r\x84nta: "; cin >> rantesats; cout << endl; } void SkrivUt() { //METOD FÖR ATT SKRIVA UT DATA cout << endl << "Namn: " << innehavare << endl; cout << "Kontonummer: " << ge_knummer() << endl; //Text och anropade variabler skrivs ut i metoden. Metoden tillkallas sen i main. cout << "Saldo: " << saldo << " kr" << endl; cout << "R\x84nta: " << ranteutbetalning() << " kr" << endl << endl; } int ge_knummer() { //METOD SOM RETUNERAR KONTONUMMER return knummer; } int ranteutbetalning() { //METOD FÖR RÄNTA return (rantesats/100)*saldo; } //VIKTIGT ATT INTE SKRIVA rantesats= FÖR DÅ RÄKNAS DET UT VARJE GÅNG MAN KALLAR FUNKTIONEN. int ranteutbetalning_alla() { return saldo+((rantesats/100)*saldo); } }; int main() { //HUVUD Konto personKonto[5]; //SKAPAR OBJEKT AV KLASS FÖR FEM BANKKONTO while(true) { //MENY LOOP int val, visa, nk; cout << "1. Nytt konto" << endl; cout << "2. Se konto: " << endl; cout << "3. Visa alla konto: " << endl; cout << "4. R\x84nteutbetalning: " << endl; cout << "5. Avsluta: " << endl; cin >> val; switch(val) { //SWITCH BÄTTRE ÄN IF VID MENYVAL TYCKER JOCKE case 1: cout << "Nytt konto, 1-5: "; cin >> nk; if(nk==1) { //SKAPAR KONTO 1-5 BEROENDE PÅ VAL personKonto[0].NyttKonto(); } else if(nk==2) { personKonto[1].NyttKonto(); } else if(nk==3) { personKonto[2].NyttKonto(); } else if(nk==4) { personKonto[3].NyttKonto(); } else if(nk==5) { personKonto[4].NyttKonto(); } else cout << ""; break; case 2: //VISAR KONTO 1-5 BEROENDE AV VAL. DEFAULT ENLIGT KONSTRUKTOR cout << "Vilket konto ska visas? 1-5: "; cin >> visa; if(visa==1){ personKonto[0].SkrivUt(); } else if(visa==2) { personKonto[1].SkrivUt(); } else if(visa==3) { personKonto[2].SkrivUt(); } else if(visa==4) { personKonto[3].SkrivUt(); } else if(visa==5) { personKonto[4].SkrivUt(); } else cout << ""; break; case 3: //LOOP SOM SKRIVER UT SAMTLIGA KONTON. TOMMA KONTON GES DEFAULT VÄRDE ENLIGT CONSTRUCTOR for(int i=0; i<5; i++) personKonto[i].SkrivUt(); break; case 4: //HAR MÖJLIGEN MISSFÖRSTÅTT VAD DETTA MENYVAL SKA GÖRA, MEN HAR FÅTT IHOP VAD JAG TROR DU ÄR UTE EFTER cout << endl << "Saldo inklusive r\x84nta vid \x86rets slut:" << endl; for(int i=0; i<5; i++) cout << "Konto: " << personKonto[i].ge_knummer() << ": " << personKonto[i].ranteutbetalning_alla() << " kr" << endl; cout << endl; break; case 5: //AVSLUTAR return 0; } } return 0; }

Någon som har tips eller idéer för hur jag ska göra och vad jag gör för fel.... Tack på förhand!

Permalänk
Medlem
Skrivet av Javajocke:

Har fastnat i en uppgift där jag ska skapa ett banksystem där man kan skapa konto och skriva in uppgifter. Så här ser uppgiften ut: Skapa klasserna KONTO och BANK. KONTO har attributen nummer, innehavare, saldo, rantesats, samt metoderna konto (konstruktor), skrivut, ge_nummer, ranteutbetalning (till alla konto). Klassen BANK har attributen konto (vektor eller array), antal konto, med metoderna bank (konstruktor), skriv_kontolista, nytt_konto, ranteutbetalning, sok_kontonr.

Jag får ihop ett fullt fungerande program om jag bara utgår från en enda klass. Men jag är helt handfallen på hur jag gör när det är två klasser inblandade. Jag förstår inte hur jag ska få den ena klassen att fungera tillsammans med den andra klassen. Här är lite vad jag skrivit. Om man väljer att se konto så kraschar programmet och jag vet inte varför.

#include <iostream> #include <vector> using namespace std; class Konto { public: int nummer; string innehavare; float saldo; float rantesats; Konto() { //KONSTRUKTUR ANGER DEFAULTVÄRDE SOM VISAS OM INGET ANNAT VÄRDE HAR ANGETTS. VÄLDIGT BRA FÖR ATT UNDVIKA ATT PROGRAMMET VISAR SKRÄPVÄRDEN. nummer=0; innehavare="KONTO EJ \x94PPNAT"; saldo=0.0; rantesats=0.0; } void setinfo(int _nummer, string _innehavare, float _saldo, float _rantesats) { nummer=_nummer; innehavare=_innehavare; saldo=_saldo; rantesats=_rantesats; } int ge_nummer() { //METOD SOM RETUNERAR KONTONUMMER return nummer; } int ranteutbetalning() { //METOD FÖR RÄNTA return (rantesats/100)*saldo; } }; class Bank : public Konto { public: int antal_konton; bank(){ antal_konton=0;} std::vector<Konto>konton; void setinfo(std::vector<Konto> _konton, int _antal_konton) { konton = _konton; antal_konton=_antal_konton; } int nytt_konto() { cout << endl << "Skriv kontonummer: "; cin >> nummer; cout << "Skriv namn: "; cin.ignore(); //RENSAR I PRINCIP CIN SÅ ATT GETLINE FUNKAR getline(cin, innehavare); // SUPERBRA DÅ DEN TAR MED ALLT MAN SKRIVER. ÄVEN MELLANRUM. KAN ALLTSÅ SKRIVA FÖR OCH EFTERNAMN cout << "Skriv in saldo: "; cin >> saldo; cout << "Skriv in % r\x84nta: "; cin >> rantesats; cout << endl; // konton.push_back(Konto(nummer, innehavare, saldo, rantesats)); } void skriv_kontolista() { for(int i=0; i<1; i++){ cout << endl << "Namn: " << konton[i].innehavare << endl; cout << "Kontonummer: " << konton[i].ge_nummer() << endl; //Text och anropade variabler skrivs ut i metoden. Metoden tillkallas sen i main. cout << "Saldo: " << konton[i].saldo << " kr" << endl; cout << "R\x84nta: " << konton[i].rantesats << " kr" << endl << endl;} } }; int main() { Konto konto; Bank bank; while(true) { //MENY LOOP int val; cout << "1. Nytt konto" << endl; cout << "2. Visa konto: " << endl; cout << "3. Ranteutbetalning: " << endl; cin >> val; switch(val) { //SWITCH BÄTTRE ÄN IF VID MENYVAL TYCKER JOCKE case 1: bank.nytt_konto(); break; case 2: bank.skriv_kontolista(); break; case 3: konto.ranteutbetalning(); break; } } return 0; }

Och så här ser mitt fungerande program ut, fast med bara en klass.

#include <iostream> using namespace std; class Konto { //SKAPAR KLASS FÖR KONTO public: string innehavare; int knummer; double saldo; double rantesats; Konto() { //KONSTRUKTUR ANGER DEFAULTVÄRDE SOM VISAS OM INGET ANNAT VÄRDE HAR ANGETTS. VÄLDIGT BRA FÖR ATT UNDVIKA ATT PROGRAMMET VISAR SKRÄPVÄRDEN. knummer=0; innehavare="KONTO EJ \x94PPNAT"; saldo=0.0; rantesats=0.0; } void NyttKonto() { //METOD FÖR ATT SKAPA NYTT KONTO cout << endl << "Skriv kontonummer: "; cin >> knummer; cout << "Skriv namn: "; cin.ignore(); //RENSAR I PRINCIP CIN SÅ ATT GETLINE FUNKAR getline(cin, innehavare); // SUPERBRA DÅ DEN TAR MED ALLT MAN SKRIVER. ÄVEN MELLANRUM. KAN ALLTSÅ SKRIVA FÖR OCH EFTERNAMN cout << "Skriv in saldo: "; cin >> saldo; cout << "Skriv in % r\x84nta: "; cin >> rantesats; cout << endl; } void SkrivUt() { //METOD FÖR ATT SKRIVA UT DATA cout << endl << "Namn: " << innehavare << endl; cout << "Kontonummer: " << ge_knummer() << endl; //Text och anropade variabler skrivs ut i metoden. Metoden tillkallas sen i main. cout << "Saldo: " << saldo << " kr" << endl; cout << "R\x84nta: " << ranteutbetalning() << " kr" << endl << endl; } int ge_knummer() { //METOD SOM RETUNERAR KONTONUMMER return knummer; } int ranteutbetalning() { //METOD FÖR RÄNTA return (rantesats/100)*saldo; } //VIKTIGT ATT INTE SKRIVA rantesats= FÖR DÅ RÄKNAS DET UT VARJE GÅNG MAN KALLAR FUNKTIONEN. int ranteutbetalning_alla() { return saldo+((rantesats/100)*saldo); } }; int main() { //HUVUD Konto personKonto[5]; //SKAPAR OBJEKT AV KLASS FÖR FEM BANKKONTO while(true) { //MENY LOOP int val, visa, nk; cout << "1. Nytt konto" << endl; cout << "2. Se konto: " << endl; cout << "3. Visa alla konto: " << endl; cout << "4. R\x84nteutbetalning: " << endl; cout << "5. Avsluta: " << endl; cin >> val; switch(val) { //SWITCH BÄTTRE ÄN IF VID MENYVAL TYCKER JOCKE case 1: cout << "Nytt konto, 1-5: "; cin >> nk; if(nk==1) { //SKAPAR KONTO 1-5 BEROENDE PÅ VAL personKonto[0].NyttKonto(); } else if(nk==2) { personKonto[1].NyttKonto(); } else if(nk==3) { personKonto[2].NyttKonto(); } else if(nk==4) { personKonto[3].NyttKonto(); } else if(nk==5) { personKonto[4].NyttKonto(); } else cout << ""; break; case 2: //VISAR KONTO 1-5 BEROENDE AV VAL. DEFAULT ENLIGT KONSTRUKTOR cout << "Vilket konto ska visas? 1-5: "; cin >> visa; if(visa==1){ personKonto[0].SkrivUt(); } else if(visa==2) { personKonto[1].SkrivUt(); } else if(visa==3) { personKonto[2].SkrivUt(); } else if(visa==4) { personKonto[3].SkrivUt(); } else if(visa==5) { personKonto[4].SkrivUt(); } else cout << ""; break; case 3: //LOOP SOM SKRIVER UT SAMTLIGA KONTON. TOMMA KONTON GES DEFAULT VÄRDE ENLIGT CONSTRUCTOR for(int i=0; i<5; i++) personKonto[i].SkrivUt(); break; case 4: //HAR MÖJLIGEN MISSFÖRSTÅTT VAD DETTA MENYVAL SKA GÖRA, MEN HAR FÅTT IHOP VAD JAG TROR DU ÄR UTE EFTER cout << endl << "Saldo inklusive r\x84nta vid \x86rets slut:" << endl; for(int i=0; i<5; i++) cout << "Konto: " << personKonto[i].ge_knummer() << ": " << personKonto[i].ranteutbetalning_alla() << " kr" << endl; cout << endl; break; case 5: //AVSLUTAR return 0; } } return 0; }

Någon som har tips eller idéer för hur jag ska göra och vad jag gör för fel.... Tack på förhand!

Du skriver att programmet kraschar, men som jag ser det borde det inte ens kompilera.
Det korta svaret och kanske viktigaste att ta med sig: Läs varningar och felmeddelanden.

Kompileringsfel 1:

konto.cc:41:10: error: ISO C++ forbids declaration of ‘bank’ with no type [-fpermissive] bank(){

Detta är bara att Bank är felstavat (bank vs Bank).

Kompileringsfel 2, om man avkommenterar raden som du har problem med:

konto.cc: In member function ‘int Bank::nytt_konto()’: konto.cc:69:68: error: no matching function for call to ‘Konto::Konto(int&, std::__cxx11::string&, float&, float&)’ konton.push_back(Konto(nummer, innehavare, saldo, rantesats)); ^ konto.cc:14:5: note: candidate: Konto::Konto() Konto() { //KONSTRUKTUR ANGER DEFAULTVÄRDE SOM VISAS OM INGET ANNAT VÄRDE HAR ANGETTS. VÄLDIGT BR A FÖR ATT UNDVIKA ATT PROGRAMMET VISAR SKRÄPVÄRDEN. ^~~~~ konto.cc:14:5: note: candidate expects 0 arguments, 4 provided konto.cc:6:7: note: candidate: Konto::Konto(const Konto&) class Konto ^~~~~ konto.cc:6:7: note: candidate expects 1 argument, 4 provided konto.cc:6:7: note: candidate: Konto::Konto(Konto&&) konto.cc:6:7: note: candidate expects 1 argument, 4 provided

Här är problemet att klassen Konto inte har någon konstruktor som tar de argument du försöker passa över. Rent principiellt ser det väl dock rimligt ut att själva interaktionen mellan klasserna är att du skapar en instans av Konto och lägga till den i vektorn i Bank, så du vill nog lägga till en sådan konstruktor. (Läs på om konstruktorer)

Vad gäller att din Bank ärver av Konto så verkar det orimligt, både i verkligheten och det du försöker modellera så är inte en bank en sorts konto. (Läs på om arv och hur det används)

Visa signatur

Desktop: Ryzen 5800X3D || MSI X570S Edge Max Wifi || Sapphire Pulse RX 7900 XTX || Gskill Trident Z 3600 64GB || Kingston KC3000 2TB || Samsung 970 EVO Plus 2TB || Samsung 960 Pro 1TB || Fractal Torrent || Asus PG42UQ 4K OLED
Proxmox server: Ryzen 5900X || Asrock Rack X570D4I-2T || Kingston 64GB ECC || WD Red SN700 1TB || Blandning av WD Red / Seagate Ironwolf för lagring || Fractal Node 304

Permalänk

Okej, så jag fick programmet att sluta krascha genom att ändra till .size():
for(int i=0; i<konton.size(); i++){

Räcker det att skriva så här för att loopen ska gå igenom alla konton?
Iaf så ville den endå inte skriva ut något :/

Permalänk
Medlem
Skrivet av Javajocke:

Okej, så jag fick programmet att sluta krascha genom att ändra till .size():
for(int i=0; i<konton.size(); i++){

Räcker det att skriva så här för att loopen ska gå igenom alla konton?
Iaf så ville den endå inte skriva ut något :/

Ah, där hade du ju också ett problem.

Har du några konton i listan då? Koden som du postade hade ju just den funktionaliteten borttagen.

Visa signatur

Desktop: Ryzen 5800X3D || MSI X570S Edge Max Wifi || Sapphire Pulse RX 7900 XTX || Gskill Trident Z 3600 64GB || Kingston KC3000 2TB || Samsung 970 EVO Plus 2TB || Samsung 960 Pro 1TB || Fractal Torrent || Asus PG42UQ 4K OLED
Proxmox server: Ryzen 5900X || Asrock Rack X570D4I-2T || Kingston 64GB ECC || WD Red SN700 1TB || Blandning av WD Red / Seagate Ironwolf för lagring || Fractal Node 304

Permalänk

@evil penguin:

Användaren ska själv lägga till konto. Så om man själv lägger till ett konto, och sen vill visa det så fungerar det ändå inte. Blir tomt. Jag har en aning om att det kan ha att göra med att jag inte får rätt på push back. Kanske läggs inte kontot riktigt in i vektorn då... Så hur ordnar jag så att pushback fungerar?

har provat

// bank nyttkonto(nummer, innehavare, saldo, rantesats);

// konton.push_back(nyttkonto);

eller
// konton.push_back(nummer, innehavare, saldo, rantesats);

Permalänk
Medlem
Skrivet av Javajocke:

@evil penguin:

Användaren ska själv lägga till konto. Så om man själv lägger till ett konto, och sen vill visa det så fungerar det ändå inte. Blir tomt. Jag har en aning om att det kan ha att göra med att jag inte får rätt på push back. Kanske läggs inte kontot riktigt in i vektorn då... Så hur ordnar jag så att pushback fungerar?

har provat

// bank nyttkonto(nummer, innehavare, saldo, rantesats);

// konton.push_back(nyttkonto);

eller
// konton.push_back(nummer, innehavare, saldo, rantesats);

Du är med på att // gör resten av raden till en kommentar, dvs det är inte kod som körs?

Visa signatur

Desktop: Ryzen 5800X3D || MSI X570S Edge Max Wifi || Sapphire Pulse RX 7900 XTX || Gskill Trident Z 3600 64GB || Kingston KC3000 2TB || Samsung 970 EVO Plus 2TB || Samsung 960 Pro 1TB || Fractal Torrent || Asus PG42UQ 4K OLED
Proxmox server: Ryzen 5900X || Asrock Rack X570D4I-2T || Kingston 64GB ECC || WD Red SN700 1TB || Blandning av WD Red / Seagate Ironwolf för lagring || Fractal Node 304

Permalänk

@evil penguin:

Jojo, satte den som kommentar för att den inte fungerar...