Warum ist der explizite Konstruktoraufruf illegal?
-
unerfahren3 schrieb:
Thx. Ich werde wohl vernünftiger Weise einen Konstruktor, der keine Parameter braucht, verwenden. Und dann eine Init() Funktion.
Das scheint die Handhabung des new-Operators zu vereinfachen.Das vereinfacht die Sache keineswegs. malloc legt keine kartenobjekte an, sondern besorgt nur den Speicher. Streng genommen müsste man an dieser Stelle ein sogenanntes placement new verwenden. Etwa so:
case 0: new (&Stapel[i]) Karte(herz); // erzeugt ein Kartenobjekt printColor(Stapel[i]);
Vereinfachen kannst Du alles, mit Hilfe eines Containers - z.B. std::vector<Karte> karten.
case 0: karten.push_back( Karte(herz) ); // erzeugt ein Kartenobjekt printColor(karten.back());
normalerweise sollte so auch kein überflüssiges Kartenobjekt angelegt werden.
unerfahren3 schrieb:
Einen Misch-Algorithmus, der möglichst Unordnung in den Kartenstapel bringen soll. Jetzt kann ich dazu <vector> nicht so gut gebrauchen, und muss mein Glück irgendwie mit einem Array versuchen, fürchte ich.
Mit dem bereits erwähnten std::random_shuffle kannst Du auch den vector<Karte> 'mischen'.
Gruß
Werner
@Edit: ich hatte campers erste Antwort zu spät gesehen ...
-
Sorry, wenn ich schon wieder da bin, es scheint, ich hab ein Verständnisproblem bezüglich malloc() und new[], letzterem 'new' wird ja nachgesagt, dass es Konstruktoren, soferne vorhanden, automatisch aufruft, was malloc() eigentlich nicht tun sollte.
malloc() sollte ja eigentlich nur den Speicher beschaffen, und das Objekt nicht erzeugen.Habe folgenden Code ausprobiert:
class mystery{ protected: short demoValue; public: mystery(); void setDemo(short someValue); short getDemo(); }; mystery::mystery():demoValue(0){} void mystery::setDemo(short someValue){ demoValue = someValue; } short mystery::getDemo(){ return demoValue; } #include <stdlib.h> #include <stdio.h> int main(){ mystery* Feld; Feld = (mystery*) malloc(sizeof(mystery)*3); // Jetzt wird's mysterioes: Feld[0].setDemo(5); /* Feld[0] ist noch nicht einmal konstruiert, sondern malloc hat ja lediglich den Speicher dafuer angefordert. Trotzdem kann man schon die Member-Funktion setDemo aufrufen, so, als waere Feld[0] durch einen Kon- struktor tatsaechlich erzeugt worden */ printf("%d", Feld[0].getDemo()); /* Und der Wert '5' ist auch problemlos in die Membervariable demoValue geschrieben worden */ fgetc(stdin); return 0; }
Weder habe ich hier explizit einen Konstruktor aufgerufen, noch habe ich new verwendet (wodurch ein Objekt implizit erzeugt werden sollte, laut meinem Buch). Es gibt weder einen Compiler-Fehler, noch tritt zur Laufzeit ein Fehler ein: Das Programm schreibt schön '5', so wie es sollte.
Wie ist es möglich, dass man die Member-Funktionen von einem Objekt, das nicht einmal konstruiert wurde, sondern für das ja nur Speicher bereitgestellt wurde, problemlos aufrufen kann (!?). Wäre es vorstellbar, dass malloc() womöglich ebenfalls implizit den Konstruktor der Klasse mystery aufruft, genau so, wie es eigentlich nur new[] machen dürfte ?
-
mystery* Feld; Feld = (mystery*) malloc(sizeof(mystery)*3); //Feld wird in einen gültigen Bereich Zeigen Feld[0].getDemo(); // wird bestimmt nicht null zurueckgeben, weil der Kontruktor nicht aufgerufen wurde
-
unerfahren3 schrieb:
Wie ist es möglich, dass man die Member-Funktionen von einem Objekt, das nicht einmal konstruiert wurde, sondern für das ja nur Speicher bereitgestellt wurde, problemlos aufrufen kann (!?).
Der Standard sagt nicht, dass ein Methodenaufruf auf ein nicht konstruiertes Objekt ein sofortiges Programmende bewirkt, sondern "undefiniertes Verhalten".
Du kannst dich nicht darauf verlassen, dass es schief geht, wenn du etwas falsch machst. Schon gar nicht, dass etwas Bestimmtes passiert.
unerfahren3 schrieb:
Wäre es vorstellbar, dass malloc() womöglich ebenfalls implizit den Konstruktor der Klasse mystery aufruft, genau so, wie es eigentlich nur new[] machen dürfte ?
Nein.
-
std::malloc ist aus C-Zeiten, wo es keine Konstruktoren gab. Demnach => Nein, tut es nicht.
Dass das geht, darf eigentlich nicht, denn der this-Zeiger wird nicht erstellt und damit besteht keine Möglichkeit auf Membervariablen zu zugreifen.
-
(D)Evil schrieb:
Dass das geht, darf eigentlich nicht, denn der this-Zeiger wird nicht erstellt und damit besteht keine Möglichkeit auf Membervariablen zu zugreifen.
Den this-Zeiger muss er auch nicht initialisieren, denn der wird bei nicht-statischen Funktionen als Parameter übergeben.
-
Soweit ich weiß , dass man malloc() nur in C verwendet und für C++ verwendet man new Typ[]....
-
Ist mir bekannt, das der übergeben wird. Dennoch muss der irgendwann erstmal erzeugt werden.
Außerdem ... new ist ein operator, malloc eine Funktion! malloc gibt void* zurück => nicht typsicher, new wirft exception wenn es nicht geklappt hat usw.
Also nimm new
-
Den this-Zeiger "erzeugst" du ja in dem Moment indem du x->y(); aufrufst. Da ist x dann der this-Zeiger. Also eigentlich ist das: y(x);
-
Da hat Fellhuhn recht. Du kannst (theoretisch) ja auch static_cast<Klasse*>(0)->foo() machen, was zwar undefiniert ist, aber auf den meisten Plattformen auch nur Klasse::foo() mit this == 0 aufruft. Der This-Zeiger muss nicht "erzeugt" werden