Was bewirkt dieser Code?
-
Also hier erstmal meine Ausgabe zu deinem Programm
NAME: IDENTNR: 999 NAME: IDENTNR: 999 NAME: IDENTNR: 999 NAME: IDENTNR: 999 NAME: IDENTNR: 999 NAME NEU: Max // < funkst bei mir also IDENT NEU: 11 HIER SOLLTE 999 stehen: 1990298837Zu deiner Reservierung. Es ist durchaus korrekt, deine Variablen im Konstruktor mit Werten vorzufüllen. Du solltest aber bedenken, das du dies bei deinem 2. Konstuktor NICHT tust. Somit ist der Wert in reservierung natürlich uninitialisiert.
-
Danke für die Antwort!
Also läuft das so ab:
1. Array fanti[5] erzeugen => Standardkonstruktor wird aufgerufen
2. neues Objekt erstelen => fanti[0] = Elefant ("Max",11); ==> der andere
Konstruktor wird aufgerufen
3. das neue Objekt wird dann in fanti[0] kopiert?Ist das dann vergleichbar wie in Java:
Elefant fanti[5]
fanti [0] = new Elefant("Max",11)??
Danke!
Viele Grüße
-
Mike1986 schrieb:
Ist das dann vergleichbar wie in Java:
Nein, bei Java hast du zunächst ein Array von Nullzeigern. Anschliessend lässt du den einen Zeiger auf ein neues Objekt verweisen. Bei C++ hingegen hantierst du hier direkt mit Objekten.
Wichtig ist der Unterschied Wertsemantik <-> Referenzsemantik.
-
BasicMan01 schrieb:
Es ist durchaus korrekt, deine Variablen im Konstruktor mit Werten vorzufüllen.
Die Werte sollten aber nicht Magic Numbers sein (999 ist für mich eine gültige Reservierung), sondern ganz klar falsch sein oder irgendwo mit const bennennt werden. Ich hätte hier -1 genommen:
Elefant(string n, int id): name(n), identnr(id) { std::fill(reservierung, reservierung+10, -1); }C++-Code mit Java zu vergleichen ist im Allgemeinen eine schlechte Idee. Wenn du gleiches Verhalten willst, solltest du
boost::ptr_vectorverwenden. Ansonsten empfehle ich dir, einenstd::vector<int>anstatt ein Array zu verwenden.
Also sowas:#include <iostream> #include <vector> #include <string> class elefant { public: elefant() : name(), identnr(999), reservierung(10, -1) { } elefant(const std::string& n, int id) : name(n), identnr(id), reservierung(10, -1); { } const std::string& name() const { return name; } int ident() const { return identnr; } int reservierung() const { return reservierung[9]; } private: std::string name; int identnr; std::vector<int> reservierung; }; int main() { std::vector<elefant> fanti(5); fanti[0] = elefant ("Max", 11); std::cout << "NAME NEU: " << fanti[0].name() << std::endl; std::cout << "IDENT NEU: " << fanti[0].ident() << std::endl; std::cout << "HIER SOLLTE 999 stehen: " << fanti[0].reservierung() << std::endl; }Habs nur im Antwortfenster geschrieben und nicht getestet, vielleicht sind ein paar syntaxfehler drin.
-
Danke für die Hilfe!
Ich habe noch eine Frage:
Das gleiche Thema mit einer anderen Klasse
Kundschaft[i] = Kunde(gehege1.kundeVornameAnlegen(), gehege1.kundeNachnameAnlegen(), gehege1.kundeTelefonnummerAnlegen(), i);in den Methoden "...Anlegen" werden hier die Werte erfasst.
Mein Frage:
Ist es normal, das zuerst die Methode kundeTelefonnumerAnlegen(), dann KundeNachnameAnlegen() und zum Schluss kundeVornameAnlegen() aufgerufen wird?
Danke!
Viele Grüße
-
Mike1986 schrieb:
Kundschaft[i] = Kunde(gehege1.kundeVornameAnlegen(), gehege1.kundeNachnameAnlegen(), gehege1.kundeTelefonnummerAnlegen(), i);in den Methoden "...Anlegen" werden hier die Werte erfasst.
Mein Frage:
Ist es normal, das zuerst die Methode kundeTelefonnumerAnlegen(), dann KundeNachnameAnlegen() und zum Schluss kundeVornameAnlegen() aufgerufen wird?
Die Auswertungsreihenfolge ist nicht definiert.
-
Mir ist gerade bei einem Array noch was aufgefallen:
#include <cstdlib> #include <iostream> using namespace std; class Elefant { //Deklaration der Attribute private: string name; //für den Namen int identnr; //für die Identifizierung int reservierung[10]; public: //der Konstruktor mit Initialisierungsliste //hier werden Defaultwerte gesetzt Elefant() : name(" "), identnr(999) { for(int i = 0; i < 10; i++) { reservierung[i] = 999; } cout <<"NAME: " <<name <<endl; cout <<"IDENTNR: " <<identnr <<endl; } Elefant(string n, int id): name(n), identnr(id) {} string getName() { return name; } int getident() { return identnr; } int getReservierung() { return reservierung[9]; } }; int main(int argc, char *argv[]) { Elefant fanti[3]; // fanti[0] = Elefant ("Max",11); fanti[0] = Elefant ("BLA",0); fanti[1] = Elefant ("BLu",1); fanti[2] = Elefant ("BLi",2); //wenn man diese Zeile auskommentiert klappt es wieder?? fanti[3] = Elefant ("BLo",3); fanti[4] = Elefant ("BLu",4); cout <<endl << endl; cout << "NAME NEU: " << fanti[0].getName() <<endl; cout << "IDENT NEU: " << fanti[0].getident() <<endl; //HIER STIMMT ES NICHT cout << "HIER SOLLTE 999 stehen: " << fanti[0].getReservierung(); system("PAUSE"); return EXIT_SUCCESS; }Das Programm bricht natürlich ab.
Allerdings läuft es wenn ich fanti[3] ausklammer??
Warum funktioniert das denn?Viele Grüße
-
Kein Wunder, wenn du ein Array von 3 Elefanten hast und auf das 4. bzw. 5. zugreifen willst. Dass das 5. geht, ist nicht weiter erstaunlich, du überschreibst nämlich irgendetwas anderes.
Entweder vergrösserst du dein Array oder du verwendest den von mir empfohlenen Vector.
-
Hallo,
ich habe nur versehentlich 3 eingegen, eigentlich sollte es 5 sein.
Dann habe ich ein bisschen rumgespielt und gemerkt dass es wenn man fanti[3] auskommentiert kein Fehler mehr erscheint?
Ich habe immer gelernt dass dann das Programm abbrechen sollte?
Viele Grüße
-
Kannst du bitte Code liefern, der deinem Programm entspricht? Ist nämlich schade, wenn wir hier ins Blaue raten müssen.
Und nein, gar nichts muss abbrechen. Auf ungültige Array-Indizes zuzugreifen resultiert in undefiniertem Verhalten, also kann alles passieren. Anders wäre das, wenn du intelligente Arrays wie
std::tr1::arrayoderboost::arrayoder in C++0xstd::arrayverwenden würdest, die könnten dir nämlich mit einer Assertion sofort Fehler aufzeigen.