überladener cast Operator
-
Hab hier folgende Aufgabenstellung:
3.1
Welche Werte gibt das folgende Programm aus?
#include <cstdio>
class complex
{
public:
double re, im;
operator double () { return re + im; }
};
complex x;
int main()
{
x.re = 1.0;
x.im = 1.0;
complex cc[2] = { {x}, {x}}; //nur diese Zeile ist in der Aufgabe 3.2 anders
printf ("%g %g\n", cc[0].re, cc[1].re);
return 0;
}
3.2.
Welche Werte gibt das folgende Programm aus?
#include <cstdio>
class complex
{
public:
double re, im;
operator double () { return re + im; }
};
complex x;
int main()
{
x.re = 1.0;
x.im = 1.0;
complex cc[2] = { x, x}; //nur jenes ist anders
printf ("%g %g\n", cc[0].re, cc[1].re);
return 0;
}
Anmerkung
Die o. a. Beispiele stammen aus „Dr. Dobbs Journal“, einer US-Fachzeitschrift für Praktiker der Software-Entwicklung.1.Frage
Hab diese beiden Programme ablaufen lassen und feststellen müssen, dass für die
Aufgabe 3.1 der überladene cast operator aufgerufen wird und für die 3.2 nicht.
Was ändern die {} beim Aufruf: complex cc[2] = { {x}, {x}}; im Gegensatz zu
complex cc[2] = { x, x}; ?2.Frage
Hab jenes mit den Visualstudio gemacht und jedes Programm lieferte unterschiedliche Werte. Wenn mann es aber mit einen GNU compiler
übersetzt nimmt er gar nicht den cast operator und beide Programme laufen identisch. Wie kann das sein?
-
sepplhuber schrieb:
... Was ändern die {} beim Aufruf: complex cc[2] = { {x},{x}}; im Gegensatz zu complex cc[2] = { x, x}; ? ...
Hallo!
Deine Klasse complex enthält keine privaten Member, keine virtuellen Funktionen, keine static Member, keine selbstdefinierten Konstruktoren und auch keine Basisklasse. Sie stellt also ein Aggregat dar (siehe Standard 8.5.1), welches auf besondere Weise initialisiert werden kann. Z.B. durch Aufzählung der Member in geschweiften Klammern:
complex y = {2.0, 3.0}; complex ay[2] = { {2.0, 3.0} , {4.0, 5.0} }; complex by[2] = { {2.0} , {4.0, 5.0} };Beim ersten Element von by wurde das zweite Member weggelassen, was dazu führt, dass es mit Null initialisiert wird.
cc[2] = { {x}, {x} };ist eigentlich nichts anderes, als
cc[0] = {x}; cc[1] = {x};Hierbei wird cc[0].re mit 2.0 initialisiert, weil es ja die Umwandlungsfunktion von complex nach double gibt. cc[0].im wird mit 0.0 initialisiert, weil dafür keine Angaben gemacht wurden. Für cc[1] passiert dasselbe.
Ohne die inneren geschweiften Klammern
cc[2] = { x, x};werden die Elemente im Array direkt mit dem Objekt x initialisiert.
sepplhuber schrieb:
... 2.Frage
Hab jenes mit den Visualstudio gemacht und jedes Programm lieferte unterschiedliche Werte. Wenn mann es aber mit einen GNU compiler
übersetzt nimmt er gar nicht den cast operator und beide Programme laufen identisch. Wie kann das sein? ...Welcher GNU-Compiler in welcher Version liefert die Werte?
Gruß
/edit/
Wenn du der Klasse complex etwas hinzufügst, das ihr den Status eines Agregats wegnimmt, z.B. ein virtuelle Funktion ist die Initialisierung im ersten Programmbeispiel nicht mehr möglich.Also, mit
class complex { public: double re, im; virtual void foo() {}; //!!! operator double () { return re + im; } };Führt die Zeile
complex cc[2] = { {x}, {x}}; //nur diese Zeile ist in der Aufgabe 3.2 anderszum Fehler.
-
Ohne Formatierung werden das nur wenige lesen. So schwer kann das doch nicht sein:
#include <cstdio> class complex { public: double re, im; operator double () { return re + im; } }; complex x; int main() { x.re = 1.0; x.im = 1.0; complex cc[2] = { {x}, {x}}; //nur diese Zeile ist in der Aufgabe 3.2 anders printf ("%g %g\n", cc[0].re, cc[1].re); return 0; }#include <cstdio> class complex { public: double re, im; operator double () { return re + im; } }; complex x; int main() { x.re = 1.0; x.im = 1.0; complex cc[2] = { x, x}; //nur jenes ist anders printf ("%g %g\n", cc[0].re, cc[1].re); return 0; }Auch ich lese erst jetzt den Code

-
Danke für die sehr hilfreiche und kompetente Antwort.
Version des Compilers muss ich erst nachfragen, da jenes Phänomen bei einem Freund auftauchte. Poste es wenn ich sie weiß.