Was bewirkt dieser Code?
-
Hallo zusammen,
Wisst ihr was dieser Code bewirkt:
Tier Hase[5]; Hase[0]=Tier(1,"Max");Bei Tier Hase[5] werden ja 5 Objekte erzeugt, bei denen der Standardkonstruktor aufegerufen wird?
Was passiert dann aber bei der ZeileHase[0]=Tier(1,"Max");Danke!
Viele Grüße
-
Da wird der
operator=aufgerufen (bei dir wahrscheinlich vom Compiler generiert), der alle Eigenschaften vonTier(1, "Max")inHase[0]kopiert.
Was herauskommt ist eigentlich logisch.
-
Es wird ein temporäres Tier Objekt erzeugt (mit den Werten 1, "Max"), dann wird dieses Objekt in das Hase Array an die Stelle mit Index 0 kopiert.
Usw.
Simon
-
Danke!
Ich habe jetzt folgendes in einer Klasse Pferd gemacht:
Pferd() : name(" "), identnr(999){} Pferd(string n, int id): name(n), identnr(id) {}In der main:
Pferd pferde[5]; pferde[0] = Pferd("Sepp",0);Also bei Pferd pferde[5] wird der Standardkonstruktor aufgerufen.
Bei pferde[0] = Pferd("Sepp",0) wird Konstruktor mit Initialisierungsliste aufgerufen?Das klappt auch alles.
Nur wenn ich z.B. den Namen ausgeben lassen möchte, dann erscheint nichts

Wenn ich anstatt
pferde[0] = Pferd("Sepp",0);einfach
pferde[0].setAttribute("Sepp",0)aufrufen würde und dann den Namen ausgeben möchte, klappt das schon.
Wisst ihr, woran das liegen kann?
Danke!
-
Die Codeschnipsel von dir sind soweit richtig.
Interessant wäre nun, wie deine Ausgabe so aussieht. Vielleicht ist da ein Fehler vorhanden.
Ich schlage vor, du postest ein abgespecktes kompilierbares Beispiel, bei dem der Fehler erkenntlich ist
-
Hallo zusammen,
hier der Code:
#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[5]; fanti[0] = Elefant ("Max",11); 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; }Ich glaube der Fehler liegt daran, dass ich die Reservierung nicht neu gesetzt habe?
Warum muss ich eigentlich die Reservierung neu setzen, sie wurde ja bereits im Standardkonstruktor neu gesetzt?Ist das mit der Reservierung und der for SChleife im Konstruktor korrekt oder eher schlechter Stil?
Danke"!
Viele Grüße
-
Mike1986 schrieb:
Warum muss ich eigentlich die Reservierung neu setzen, sie wurde ja bereits im Standardkonstruktor neu gesetzt?
Aber du konstruierst ein neues Objekt
Elefant ("Max",11)und benutzt dabei einen Konstruktor, der die Reservierung nicht setzt. Und dann kopierst du dieses neue Objekt mit der uninitialisierten Reservierung über das alte.
-
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.