Default-Konstruktor funktioniert nicht. Warum?
-
SchlippSchlapp schrieb:
Artikel art2();Lass die Klammern weg, sonst kann der Compiler die Variablendeklaration nicht von einer Funktionsdeklaration unterscheiden.
Also
Artikel art2;mfg Martin
-
Das ist einleuchtend.
Bedeutet also, wenn ich ein Objekt durch den Default-Konstruktor initialisieren lassen will, muss ich die Klammer für die Parameterliste immer wegfallen lassen?@Nexus
Danke schonmal für den Hinweis, dies hat mir mein Lehrbuch leider noch nicht mitgeteilt.
-
SchlippSchlapp schrieb:
Das ist einleuchtend.
Bedeutet also, wenn ich ein Objekt durch den Default-Konstruktor initialisieren lassen will, muss ich die Klammer für die Parameterliste immer wegfallen lassen?Nicht immer. Das ist legal:
Artikel *art2 = new Artikel();Aber am besten ist es die Klammern immer wegzulassen, dann gibt es auch keine Interpretationsprobleme.
Artikel *art2 = new Artikel;Übrigens, das ist kein Defaultkonstruktor. Du hast ihn ja definiert.
mfg Martin
-
Mein Buch schrieb:
Ein Konstruktor ohne Parameter heißt Default-Konstruktor. (...)
Falls für eine Klasse kein Konstruktor definiert ist, erzeugt der Compiler eine Minimalversion des Default-Konstruktors als public-Element.
-
SchlippSchlapp schrieb:
Mein Buch schrieb:
Ein Konstruktor ohne Parameter heißt Default-Konstruktor. (...)
Falls für eine Klasse kein Konstruktor definiert ist, erzeugt der Compiler eine Minimalversion des Default-Konstruktors als public-Element.Na gut. Stroustrup schreibt das auch. Vergiss also meinen Schmarrn. Ich find's aber unlogisch. Aber was soll's Namen sind Schall und Rauch.
mfg Martin
-
Meine Fragen sind erstmal geklärt.
Danke für die Hilfe!
-
mgaeckler schrieb:
Nicht immer. Das ist legal:
Artikel *art2 = new Artikel();Aber am besten ist es die Klammern immer wegzulassen, dann gibt es auch keine Interpretationsprobleme.
Artikel *art2 = new Artikel;Die beiden Codezeilen sind semantisch nur äquivalent, falls
Artikelkein POD-Typ ist. Bei einem solchen führt die erste Schreibweise nämlich zu einer Null-Initialisierung, während die zweite das Objekt nicht initialisiert.int* a = new int; // *a hat undefinierten Wert int* b = new int(); // *b == 0 delete a; delete b;
-
Du solltest dich auch mal mit Default-Parametern und Initialisierungslisten beschäftigen. Im Prinzip reicht dir nämlich ein einziger Konstruktor!
class Artikel { public: Artikel( long k_nr=anzart, const std::string& bez="undefiniert", double preis=0.0 ); }; Artikel::Artikel(long k_nr, const std::string& k_bez, double k_preis) : nr(k_nr), bez(k_bez), preis(k_preis) { anzart++; cout<<"Es wird ein Objekt f\201r den Artikel " << k_nr <<" angelegt"<<endl; cout<<"Dies ist der "<<anzart<<"-te Artikel"<<endl; }Was aber noch viiiiiel wichtiger ist:
Du verwendest in deinem Header "Artikel.h" als Parameter nur "string". Das sagt mir, dass in deinem Header ein "using namespace std;" steht. DAS IST BÖÖÖÖSE!
Problem: Du leerst den kompletten std-Namensraum in deinem Header aus, somit auch in jeder Einheit, die deinen Header (und natürlich Header, die deinen Header includen, usw.) einbinden! Das führt unweigerlich irgendwann zu Namenskonflikten und anderen Schweinereien
Das gilt übrigens nicht nur für std, sondern immer:
Kein using namespace xyz; in Headern!
-
Nexus schrieb:
Die beiden Codezeilen sind semantisch nur äquivalent, falls
Artikelkein POD-Typ ist. Bei einem solchen führt die erste Schreibweise nämlich zu einer Null-Initialisierung, während die zweite das Objekt nicht initialisiert.int* a = new int; // *a hat undefinierten Wert int* b = new int(); // *b == 0 delete a; delete b;Interessant. Das wußte ich nicht. Ich dachte PODs haben grundsätzlich keinen Konstruktor.
mfg Martin
-
Ui, noch ein wichtiger Nachtrag:
- Ich hab nen Fehler eingebaut: Wenn du einen Parameter für k_nr eingibst, wird der Wert für anzart nich hochgezählt. Ich korrigier das im vorigen Post.
- Dein Programm enthält einen logischen Fehler. Du gibst dem Benutzer deiner Klasse die Möglichkeit, entweder eine Artikelnummer automatisch vergeben zu lassen (über den default-Konstruktor; namentlich "anzart", die Anzahl der Artikel). Andererseits kann er auch eine eigene Nummer vergeben. Problem: Es können Artikelnummern mehrfach vergeben werden!
Lösung: Entweder komplett automatisch (laufende Nummer), oder prüfen ob die Nummer eindeutig ist. Dafür musst du natürlich irgendwo auf sämtliche Artikelnummern zugreifen können
-
mgaeckler schrieb:
Ich dachte PODs haben grundsätzlich keinen Konstruktor.
Das stimmt auch, dennoch ist die Initialisierungssyntax die gleiche wie bei Klassen mit Konstruktoren. Nur eben dass ohne die Klammern keine Initialisierung stattfindet.
-
@l'abra d'or
explicitnicht vergessen!
-
l'abra d'or schrieb:
[...]
Kein using namespace xyz; in Headern!Das hatte ich schonmal irgendwo aufgeschnappt. Vielen Dank für die Auffrischung. Setze das gleich auf meine "Wichtige Dinge, die ich ständig vergesse"-Liste.
l'abra d'or schrieb:
[...]
Problem: Es können Artikelnummern mehrfach vergeben werden!
[...]Das war nicht gefordert
(Prinzipiell hast du natürlich recht)