ü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 anders
    

    zum 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ß.


Anmelden zum Antworten