Initialisieren von Variablen



  • Hallo,
    ich würde gerne wissen, welche Methode die Beste ist, Variablen beim Erstellen zu "leeren".
    Bisher habe ich folgendes gemacht:

    struct STest {
    	int a, b, c;
    };
    
    int main() {
    	STest t;
    	ZeroMemory(&t, sizeof(t));
    
        return 0;
    }
    
    int main() {
    	STest t = { 0, 0, 0 };
    
        return 0;
    }
    

    Welche der beiden Methoden ist schneller? (Im Beispiel ist es vielleicht egal, aber bei größeren Strukturen nicht)
    MfG,
    Max



  • Ersteres benutzt eine Methode die nicht zum Iso-Standard gehört und somit bleibt nur noch eine Variante übrig.

    Und glaube mir es spielt keine Rolle.



  • Was macht ZeroMemoryß!?!?!?!??!?!?!?!?!?!??!?!?!



  • Benutze einfach einen Default-Konstruktor:

    struct STest
    {
        int a, b, c;
    
        STest() : a(0), b(0), c(0) /* (Initialisierungsliste) */ { }
    };
    
    int main()
        {
            STest t; // Und somit sind alle Attribute definitiv 0
        }
    

    Grüße.. Heiko



  • Ersteres benutzt eine Methode die nicht zum Iso-Standard gehört und somit bleibt nur noch eine Variante übrig.

    Ups, hätte ins WinAPI Forum gemusst.. sry 😞

    @bwbg:
    Das ist natürlich am besten! Danke 🙂



  • Oder alternativ:

    STest t = {};
    

    Stell die Frage nochmal, wenn dir ein Profiler exakt diese Stelle als No.1 Flaschenhals in deiner Anwendung anzeigt. Davor nimm am besten eine einfache, standardkonforme, lesbare, für jeden Menschen verständliche Form.



  • [quote="ripmav"]

    Ersteres benutzt eine Methode die nicht zum Iso-Standard gehört und somit bleibt nur noch eine Variante übrig.

    Ups, hätte ins WinAPI Forum gemusst.. sry 😞

    [quote]

    Das hat mit WinAPI an sich nix zu tun.
    ZeroMemory ist nix anderes als ein Makro:
    #define ZeroMemory(ptr, size) memset(ptr, 0, size)
    Wrnn schon, dann ins ANSI C Forum 😛
    lg



  • ripmav schrieb:

    ich würde gerne wissen, welche Methode die Beste ist, Variablen beim Erstellen zu "leeren".

    Hallo Max,

    Eine Variable kann man nicht 'leeren'; es steht immer etwas darin, z.B. der Wert 0. Was Du meinst nennt man initialisieren. Dafür gibt es in C++ die sogenannte Initialisierungsliste. Dabei werden die Variablen der Struktur beim Anlegen der Struktur unmittelbar initialisiert.

    struct STest {
        STest()
            : a(0), b(0), c(0)
        {}
        int a, b, c;
    };
    
    int main() {
        STest t;    // 't' ist fertig initialisiert
        return 0;
    }
    

    Im Sinne von C++ ist dies die 'beste' Methode - wahrscheinlich auch die schnellste, da es dem Compiler überlassen wird, die Variablen zu belegen. Es ist unwahrscheinlich, dass irgendetwas 'handmade' schneller ist.
    Eine Initialisierungsliste ist gerade bei 'größeren Objekten' wärmstens zu empfehlen. (siehe auch Scott Meyers; Effektiv C++ programmieren; Item 12)

    Gruß
    Werner



  • Halb OT

    Das Ganze lässt sich natürlich noch etwas flexibler gestalten:

    struct STest
    {
        int a, b, c;
    
        STest(int pa = 0, int pb = 0, int pc = 0) /* (Standardwerte) */
            : a(pa), b(pb), c(pc) /* (Initialisierungsliste) */
            { }
    };
    
    int main()
        {
            STest t; // Und somit sind alle Attribute definitiv 0
            STest u(1, 2, 3); // Fertig initialisiert mit Werten.
        }
    

    Grüße... Heiko



  • @bwbg: klassischer Fall von "explicit" vergessen 🙂

    @ripmav: Beide Versionen sollten, einen guten, optimierenden Compiler vorausgesetzt, etwa gleich schnell sein. Auch bei grösseren Strukturen. Allegmein solltest du dir über sowas aber keine Gedanken machen.

    premature optimization is the root of all evil in programming.



  • voll OT

    @bwbg: klassischer Fall von "explicit" vergessen 🙂

    Du wirst lachen. Bis vor 5 Minuten kannte ich das Schlüsselwort noch gar nicht. Liegt wahrscheinlich auch daran, dass ich bisher nie in die Verlegenheit kam, etwas derartiges nutzen zu müssen.

    Nach den Beschreibungen scheint es aber auch eine recht nützliche Sache zu sein.

    struct STest
    {
        int a, b, c;
    
        explicit
        STest(int pa = 0, int pb = 0, int pc = 0) /* (Standardwerte) */
            : a(pa), b(pb), c(pc) /* (Initialisierungsliste) */
            { }
    };
    
    STest s; // Konstrukturaufruf mit Standwardwerten
    STest t(1, 2, 3); // Expliziter Konstruktoraufruf
    STest u(1, 2); // Dito
    STest v = 1; // Fehler: Mit "explicit" nicht __mehr__ möglich
    
    // Ohne "explicit" würde 'STest v = 1' implizit umgewandelt in
    //  'STest v = STest(1)'
    

    Wieder was gelernt.

    Es ist natürlich wieder fallabhängig. Bei einer Klasse, welche Komplexe Zahlen repräsentiert, ist das "explicit"-Schlüsselwort bei einem Konstruktor a la 'Complex(double const& real = 0.0, double const& imaginary = 0.0)' wenig sinnvoll, da hier 'Complex c = 1.0' eine "normale" reelle Zahl bzw. c = 1 + 0i definieren kann.

    Grüße... Heiko



  • ripmav schrieb:

    Hallo,
    ich würde gerne wissen, welche Methode die Beste ist, Variablen beim Erstellen zu "leeren".
    Bisher habe ich folgendes gemacht:

    struct STest {
    	int a, b, c;
    };
    
    int main() {
    	STest t;
    	ZeroMemory(&t, sizeof(t));
    
        return 0;
    }
    
    int main() {
    	STest t = { 0, 0, 0 };
    
        return 0;
    }
    

    Welche der beiden Methoden ist schneller? (Im Beispiel ist es vielleicht egal, aber bei größeren Strukturen nicht)
    MfG,
    Max

    ich nehm immer

    memset( &t, 0, sizeof(t) )
    

    und jetzt schlagt mich 😉



  • It0101 schrieb:

    ich nehm immer

    memset( &t, 0, sizeof(t) )
    

    und jetzt schlagt mich 😉

    Funktioniert nur garantiert, wenn es ein POD ist. Außerdem machst du so Annahmen über die binäre Darstellung (böse!) und arbeitest am Compiler vorbei bzw. für den Compiler intransparent. "never ever try to be smarter than your compiler. furthermore never lie to your compiler."

    Genug handfeste Gründe, eine der anderen Varianten zu bevorzugen.

    Edit: Legasthenie 🤡



  • Es ist natürlich wieder fallabhängig. Bei einer Klasse, welche Komplexe Zahlen repräsentiert, ist das "explicit"-Schlüsselwort bei einem Konstruktor a la 'Complex(double const& real = 0.0, double const& imaginary = 0.0)' wenig sinnvoll, da hier 'Complex c = 1.0' eine "normale" reelle Zahl bzw. c = 1 + 0i definieren kann.

    Ja da stimme ich dir zu, für ein "complex" Klasse ist explicit bei den Konstruktoren nicht angesagt.
    Allerdings für vielleicht 90% aller Konstruktoren die man schreibt ist es IMO sehr angesagt. Dummer Oversight bei der Entwicklung von C++, explicit musste nachträglich dazugefummelt werden, sonst wäre es standard (und es gäbe ein "implicit" oder ähnliches stattdessen).



  • Sehr interessant. Explicit kannte ich auch noch nicht 😉
    Danke für die Erklärung..


Anmelden zum Antworten