Konstruktor kann nur 1x aufgerufen werden, oder?
-
In meinem Buch steht, man darf das machen:
// Klasse Euro wie in meinem letzten Thread Euro verkauf; verkauf += Euro(1.49);(+= wurde normal überladen)
Also ist der Aufruf: verkauf.operator+=( Euro(1.49));
Die Operatorfunktion erwartet aber const Euro&.
Im Buch steht, der Euro-Konstruktor erzeugt aus dem double-Wert ein Euro-Objekt.
Ich dachte, man kann einen Konstruktor gar nicht aufrufen und der wird automatisch aufgerufen beim erzeugen des Objekts?
Für welches Objekt wird der da überhaupt aufgerufen? Sieht aus wie ein globaler Konstruktor

-
Genau, ein Konstruktor darf nur einmal für jedes Objekt aufgerufen werden. Genau das passiert hier: Du rufst den Konstruktor von Euro mit einem double-Wert auf. Ohne ein damit verknüpftes Symbol erzeugt der Konstruktor allein ein temporäres Objekt von Euro, und übergibt dieses an den operator+=. Danach wird das temporäre Euro-Objekt wieder gelöscht. Im Grunde passiert dies (nur ohne den Namen "temp")
Euro verkauf; { const Euro temp(1.49); verkauf += temp; } // temp wird hier gelöscht
-
Ausprobieren!
#include <iostream> using namespace std; class Euro { public: Euro(double wert = 0) : m_wert(wert) { cout << "Konstruktor mit " << m_wert << " Euro!" << endl; } Euro operator+=(const Euro &euro) { return Euro(m_wert + euro.m_wert); } private: double m_wert; }; int main() { Euro verkauf; verkauf += Euro(1.49); verkauf += 3; cin.get(); }
-
hoppla
Euro &operator+=(const Euro &euro) { m_wert += euro.m_wert; return *this; }
-
"Ohne ein damit verknüpftes Symbol erzeugt der Konstruktor allein ein temporäres Objekt von Euro"
Das wusste ich nicht. Entweder ich habs überlesen oder es steht nicht im Buch.
(2. Ausgabe von Lernen und prof. anwenden, hätte gern die 3. :()
-
Sind diese beiden Ausrücke eigentlich äquivalent?
(Euro)1.49 Hier wird doch double in Euro gecastet, also der Ausdruck repräsentiert ein Euro-Objekt, oder? Aber wie weiß man, welches Element mit 1.49 initialisiert wird?
Euro(1.49)
...
-
Hallo
nein das ist nicht äquivalent.
Das erste ist ein C-style Cast, das zweite ein Konstruktor-Aufruf. beides brauch aber einen passenden L-Value, dem das ergebnis zugewiesen wird, ansonsten verfällt dieses.bis bald
akari
-
Ein Cast der eine Umwandlung erfordert kann auch ein temporäres Objekt erzeugen, wenn erforderlich. An die privaten Daten eines Objekts kommst Du ja nicht ran, deshalb schreibt er den Wert auch nicht einfach in das erste (erstbeste) Datenfeld. Die beiden Ausdrücke sind äquivalent.
Anders ist es wenn eine Konvertierung verfügbar ist, aber dann wird es der Compiler ziemlich wahrscheinlich weg optimieren.
// Nicht zwingend äquivalent: int x = (int)3.25; // explizite double nach int Konvertierung int x = int(x); // implizite double nach int Konvertierung und Erzeugung eines temporären int, darf aber wegoptimiert werden wodurch es wieder zu obiger Form äquivalent wird
-
akari schrieb:
nein das ist nicht äquivalent.
Das erste ist ein C-style Cast, das zweite ein Konstruktor-Aufruf.Was passiert denn bei einem C-Style Cast für den keine implizite Umwandlung bereitsteht, wenn nicht eine temporary Konstruktion?
-
Danke... ich werde versuchen es zu verstehen.
Ist nicht ganz einfach, C++ bietet ja sehr viele Möglichkeiten
-
Hallo
der Cast läßt einfach auf den Speicherbereich, der hinter der Variablen a vom Typ A liegt, als Typ B zugreifen.
Beispiel :int a = 0; float* b = (float*)(&a);wird kompilieren, aber verursacht beim Verwenden von *b undefinierte Fehler.
bis bald
akari
-
Aber wie kann ein int-Typ in einen Klassen-Typ gewandelt werden?
Das verstehe ich nicht... Was wird wohin kopiert..
-
Hallo
was für ein int-Wert wird in was für eine Klasse verwandelt? Wenn du dein Euro() besipiel meinst, das ist ein double-Wert.
Die Klasse hat ein Konstruktor, der als Parameter ein double zuläßt. Das können auch ganz andere, von der eigentlichen Klasse unabhängige Typen sein. Ein Konstruktor ist was die Parameter angeht wir eine normale Funktion.bis bald
akari
-
Ich meinte das:
(Euro)1.49Das ist doch kein Konstruktor-Aufruf...
-
Das meinte ich auch als Frage an akari

Das mit dem Zeigerbeispiel war mir wohl klar, trifft hier aber ziemlich sicher nicht zu. Was stattdessen, da lasse ich mich gerne belehren, aber ein (Euro)2.56 versucht ziemlich sicher nicht eine Speicherzelle an der sich ein double befindet als Euro-Objekt zu interpretieren.
Einfachstes Beispiel:
string a = (string) "Hallo, Welt";Wenn der Cast hier das Literal als Verwaltungsdaten für die Klasse string interpretieren würde, wäre das wohl ziemlich tödlich

-
Hallo
in beiden Fälle nwird tatsächlich der Konstruktor der jeweiligen Adresse aufgerufen. Das kann aber nur passieren ,wenn ein Konstruktor für genau diesen Parameter definiert ist.
Dann wir also ein tempöräres Objekt erstellt und per Zuwesiungoperator an den L-Value übergeben.bis bald
akari
-
Frinz bedankt sich.