Anfängerfrage: Konsolen"menü" Ein- und Ausgabe
-
Hmm,
man muss es aber nicht auslagern, oder?
Denn so umfangreich ist das ja nicht was ich hier mache und ich glaube wenn es noch an einigen Stellen hapert ist es ganz praktisch das beisammen zu haben.Was mich zur nächsten Frage bringt.
Wenn ich da jetzt deine Klasse übernehme, ist doch in der ersten Public-Zeile der Konstruktor oder?
Irgendwie steh ich jetzt total auf dem Schlauch was meine main Funktion betrifft.
Ich muss doch jetzt im ersten Menüpunkt per Konstruktor dem Auto meine Eigenschaften zuweisen.
Er sagt mir aber es ist kein Standardkonstruktor vorhanden.
-
Nein musst du nicht.
Ja, dass ist mein Konstruktor. Ich weiß zwar nicht, was du jetzt genau meinst, aber ich probiere es mal: Ein Konstruktor wird, wenn du ihn nicht explizit definierst, vom Compiler generiert, genau so wie ein Copy-Konstruktor, Destructor, Zuweisungsoperator.
Ein Konstruktor hat den Syntax einer Funktion, ist auch eine, aber eben eine spezielle Funktion, um für ein Objekt Speicher zu reservieren, es zu Initialisieren.Beispiel:
class Auto{ private: std::string name; int ps; int gewicht; int raeder; public: Auto(std::string n, int p, int g, int r) : name(n), ps(p), gewicht(g), raeder(r){} int get_leistung() const { return ps;} int get_gewicht() const { return gewicht;} int get_raeder() const { return raeder;} }; int main(){ Auto Mercedes("mercedes SLK", 470, 2300, 4); //erfundene Werte std::cout<<"PS: "<<Mercedes.get_leistung(); std::cout<<"Gewicht: "<<Mercedes.get_gewicht(); std::cout<<"Raeder: "<<Mercedes.get_raeder(); }Hier wird ein Object namens Mercedes ins Leben gerufen. Mit diesem Objekt kannst du allerlei anstellen, indem du deine Memberfunktionen benutzt.
Du kannst auch mehrere Konstruktoren definieren, wenn du zum Beispiel manche sachen nicht benötigst.
Auto(std::string n, int p, int g, int r); Auto(std::string n, int p, int g); Auto(std::string n, int p); Auto(std::string n); Auto();oder ihnen Default-werte übermitteln:
Auto(std::string n, int p, int g, int r=4);Jetzt klarer? Sonst musst du mal deinen Code posten.
gruß
syntax
-
Erstmal danke für die Hilfe heute, weiter werd ich erst morgen machen

#include "stdafx.h" #include <iostream> using namespace std; class Auto{ private: int leistung; int gewicht; public: Auto(int l, int g) : leistung(l), gewicht(g){} int getleistung() const {return leistung;} int getgewicht() const {return gewicht;} void setleistung(int l); void setgewicht(int g); }; int _tmain() { int eingabe; int PS; cout << "Menue:" << endl; cout << "(1) Eingabe neuer Daten" << endl; cout << "(2) komplette Ausgabe" << endl; cout << "(3) nur Gewicht und Leistung" << endl; cout << "Eingabe:"; cin >> eingabe; switch(eingabe){ case 1: cout << "Fahrzeugeingabe" << endl; Auto A (400, 1000); std::cout<<"ps: " <<A.getleistung(); } return 0; }Das funktioniert so auch.
Aber:
Wenn ich die Werte für Leistung usw. nicht in den Code schreiben will sondern eben per Eintrag in der Konsole (um mir dann eine Liste zu machen mit Name, Farbe oder so, was man dann auch mal als txt speichern kann usw.) muss ich doch statt der Werte dann die Variablen nehmen.
Und dann mit cin und mercedes.setleistung (als bsp.) einfügen.
Da und wenn ich das versuche meckert er. Liegt das schlicht daran, dass am Anfang eben diese Werte als Const angenommen werden?
-
Du musst die Werte nicht direkt in den Konstruktor einschreiben, du kannst das genau so von der Konsole machen, von der Date holen und in eine Datei schreiben...
Beispiel:
std::string name; int ps, gewicht, raeder; std::cin>>name>>ps>>gewicht>>raeder; Auto Neues_Auto(name, ps, gewicht, raeder);gruß
syntax
-
@Syntax_error
Denkst du nicht, dass Klassen für den armen Kerl erstmal zu viel sind? Natürlich ist es so richtig, wie du es vorschlägst, aber wie der OP schon meinte, ist er kompletter Anfänger.
@OP
Mach dich mal mit normalen Ein- und Ausgaben vertraut und schau dir gegebenenfalls Schleifen und switch-Anweisungen an.
Wenn du ein Menü haben willst, welches verschieden oft ausgeführt werden soll, kannst du das über eine while-Schleife regeln (evtl. do-while), die solange ausgeführt wird, bis der Benutzer die Auswahl zum Beenden benutzt. Mit der switch-Anweisung kannst du die Eingabe verarbeiten, um heraus zu finden, ob der Benutzer z.B. den Namen, das Gewicht usw. eingeben will.
Schlüsselwörter sind also:
while und do-while Schleifen, switch-Anweisungen, Variablen, Ein- und Ausgabe und wenn du schon dabei bist, vielleicht auch if-Abfragen.
Also so ziemlich das Standardprogramm was man am Anfang durchkauen sollte.
-
Moin

Also, erstmal habe ich mir jetzt das Buch "C++ Objektorientiertes Programmieren von Anfang an" gekauft

Daher hab ich den Kram nochmal neu geschrieben um mich dabei am Buch zu orientieren. Hoffe da fühlt sich jetzt keiner auf den Schlipps getreten.Mein Ergebnis ist jetzt ein Programm in das ich mehrere Objekte (Autos) einsetzen kann, und auch direkt wieder ausgeben.
Mein nächster Schritt wäre jetzt, nach der Eingabe in Punkt 2 oder 3 springen zu können um den Kram mit bestimmten Eigenschaften, oder später mal sortiert, wieder auszugeben.
Da weiss ich nicht wie ich dann auf meine verschiedenen Eingaben zugreifen soll. Meiner Meinung nach überschreiben sich so ja die neuen Autos immer gegenseitig.
Sprich was muss in case 2 rein?Hier mein Werk

// test2.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung. // #include "stdafx.h" #include <iostream> using namespace std; class Auto { private: char name[20]; int leistung; int gewicht; public: void nameSetzen(); void nameLesen(); void leistungSetzen(); void leistungLesen(); void gewichtSetzen(); void gewichtLesen(); void kilowattLesen(); }; void Auto::nameSetzen() { cin >> name; } void Auto::nameLesen() { cout << "\n" << name; } void Auto::leistungSetzen() { cin >>leistung; } void Auto::leistungLesen() { cout << "\n" << leistung; } void Auto::gewichtSetzen() { cin >>gewicht; } void Auto::gewichtLesen() { cout << "\n" << gewicht; } void Auto::kilowattLesen() { cout << "\n" << leistung/2; } int main() { int eingabe=1; int anzahl; int i; while (eingabe !=4){ cout << "Menue:" << endl; cout << "(1) Eingabe neuer Daten" << endl; cout << "(2) komplette Ausgabe" << endl; cout << "(3) nur Gewicht und PS" << endl; cout << "(4) Exit" << endl; cout << "Eingabe:"; cin >> eingabe; {switch(eingabe){ case 1: cout << "\nAnzahl der neuen Autos eingeben :"; cin >> anzahl; for (i=0;i<anzahl;i++) { Auto Neu; cout << "\nBitte Namen eingeben :"; Neu.nameSetzen(); cout << "\nBitte Leistung eingeben :"; Neu.leistungSetzen(); cout << "\nBitte Gewicht eingeben :"; Neu.gewichtSetzen(); cout << "\nName :"; Neu.nameLesen(); cout << "\nGewicht :"; Neu.gewichtLesen(); cout << "\nPS :"; Neu.leistungLesen(); cout << "\nKilowatt :"; Neu.kilowattLesen(); } break; case 2: } }} return 0; }
-
Du musst deine neu erstellen Autos auch irgendwo abspeichern, damit du später wieder Zugriff auf sie hast. Da empfehle ich dir vector.
Also immer wenn du ein neues Auto erstellst und die Eingaben fertig sind, machst du danachcars.push_back(neues_auto);Später kannst du dann mit einem Iterator, oder einer simplen for-Schleife durch alle Objekte, die in deinem Vector enthalten sind, durch iterieren und die einzelnen Methoden für die Eigenschaften aufrufen.
-
Also das bedeutet dann:
Ich muss noch #include <vector> benutzen,
dann in meiner main einen vector erstellen, den ich z.B. cars nenne, daher -> vector<char> cars; ?Und nach meiner Eingaben müsste ich dann mit cars.push_back(Neu); das grade erstellte hinten in den vector einfügen?
-
Richtig, doch der vector lautet
std::vector<Auto> cars; //nicht std::vector<char> carsgruß
syntax
-
Okay.
Dann speicher ich doch das jeweilige Auto mit allen Eigenschaften an einer Position des vectors.
Macht das nicht Probleme wenn ich dann je nach Menüpunkt nur bestimmte Eigenschaften ausgeben will?
-
Und ein anderes Problem.
Ich dachte mir, zum ausgeben greif ich auf ein bestimmtes Element zu mit Hilfe von vector.at(i).
also:
cout << cars.at(1)
Aber er sagt "Kein "<<" Operator stimmt mit diesen Operanden überein.
Was bedeutet das denn?
-
Das liegt daran, dass du nicht einfach so ein Auto-Objekt ausgeben kannst. Du musst es also ungefähr so schreiben
cars.at(1).leistungLesen();
-
Hm, das hat nicht funktioniert.
Muss ich evtl diesen << Operator überladen?Allerdings weiß ich nicht was das genau bedeutet. Wird damit der original operator sozusagen ersetzt?
also irgendwie std::ostream& operator << (std::ostream, cars) ?
-
So wie ich es geschrieben habe, sollte es funktionieren. Du brauchst ja nicht nochmal std::cout << zu schreiben, dass hast du doch schon in deinen leseLeistung usw. Methoden drin, wobei das natürlich nicht so die feinste Art ist, aber das ist momentan ja nicht so wichtig.
-
FreakY<3Cpp schrieb:
So wie ich es geschrieben habe, sollte es funktionieren. Du brauchst ja nicht nochmal std::cout << zu schreiben, dass hast du doch schon in deinen leseLeistung usw. Methoden drin, wobei das natürlich nicht so die feinste Art ist, aber das ist momentan ja nicht so wichtig.
Schande über mein Haupt.
Man muss natürlich dran denken, dass der vector bei 0 anfängt...Und warum ist das nicht die feinste Art? Ich finde das grade äußerst fein

Ich versuch da jetzt mal was mal sehen ob es klappt.
-
Weil man eine Klasse immer so gestalten sollte, dass sie äußerst flexibel und benutzerfreundlich ist. Benutzerfreundlich ist hiermit gemeint, dass andere Leute deine Klasse benutzen können, ohne etwas zu verändern und wenn sie einfach nur den Wert des Gewichts wollen, aber keine Ausgabe haben wollen, oder weil sie evtl. die WinAPI nutzen, oder was auch immer, stört dein cout.
D.h., aus deinen Methoden solltest du das hier machenvoid Auto::nameSetzen(string name) { this->name = name; } string Auto::nameLesen() { return this->name; } void Auto::leistungSetzen(int leistung) { this->leistung = leistung; } string Auto::leistungLesen() { return this->leistung; } void Auto::gewichtSetzen(int gewicht) { this->gewicht = gewicht; } int Auto::gewichtLesen() { return this->gewicht; } int Auto::kilowattLesen() { return this->leistung / 2; } int main() { //... //erster Wagen std::cout << cars.at(0).gewichtLesen(); }Die Namen werden am besten dann noch zu "getgewicht" und "setgewicht", wobei Deutsch und Englisch nicht gemischt werden sollten und du gleich alles Englisch schreibst.
-
Ok das seh ich ein.
Dann hab ich noch eine kleine Frage eher praktischer Natur.
Da es Visual Studio für mich umsonst gibt hab ohne viel überlegen eben das genommen.
Aber wo kann ich denn da den Pfad angeben in den er mir die erzeugte *.exe legen soll?
-
Die wird eigentlich immer in dem Ordner deines Projekts erstellt. Schau mal im Debug Ordner nach.
-
Ok, das wusste ich, ich dachte nur, dass es quasi so ein "speichern unter" Äquivalent gibt.
Dann hab ich aber tatsächlich noch eine Frage zum Kompiler.
Das unter Visual St. kompilierte Programm scheint eine bestimmte *.dll zu benötigen.
Scheinbar hat das was mitusing namespace std;
#include "stdafx.h"zu tun.
Gibts einen Weg das so zu kompilieren, dass es überall läuft, aber OHNE überall vor jedes cout, cin, endl std:: schreiben zu müssen? ^^