Ist die Init Reihenfolge der Klassen festgelegt?



  • Hallo Forum,

    ich habe eine Hauptklasse die eine paar static Member hat und diese per static Getter anbietet. Kann ich diese Getter nun zur Initialisierung von static Variablen in anderen Klassen nehmen? Scheinbar scheint es zu funktionieren. Kann ich mich darauf verlassen?

    Wann werden eigentlich die static Variablen initialiisert? Erst wenn die Klasse das erste mal benötigt wird oder gleich am Start?

    Vielen Dank

    Luigi



  • Ich will nicht so viele Threads aufmachen. Noch ne Frage:

    while (1) {
     int i = MyFunc();
     Dosomething();
    }
    

    Wird hier das i immer wieder neu auf dem Stack angelegt oder kann ich das so schreiben? ->Performace, insbesondere wenn anstatt des int eine Klasse genommen wird. Mich interessiert der Standard. Die Kompiler mögen da vielleicht optimieren.



  • Wenn du die Erzeugung deiner statischen Variable in einer Funktion kapselst, erfolgt die Erzeugung beim erstmaligen Aufruf.
    Globale Objekte werden vor dem Eintritt in die main() initialisiert.
    Da static-Variablen nicht an Klasseninstanzen (aka Objekte) gebunden sind, erfolgt die Erstellung mit dem ersten Objekt.

    Zu deiner zweiten Frage:
    Sobald das "i" den Scope verlässt wird es zerstört. Also nach jedem Schleifendurchlauf.
    Ob Compilerhersteller da optimieren kann ich nicht sagen.
    Bei einem int ist das nicht so schlimm.



  • SuperMario_Y schrieb:

    Ob Compilerhersteller da optimieren kann ich nicht sagen.
    Bei einem int ist das nicht so schlimm.

    Das ist eine der primitivsten Compileroptimierungen. Über soetwas sollte man sich heutzutage als Programmierer keine Gedanken mehr machen müssen.



    1. Es gibt die Regel "Eine Frage, ein Thread". Wenn du mehrere Fragen haben solltest mach bitte einen eigenen Thread für jede Frage auf.

    Statische Variablen werden vor dem Aufruf von main() initialisiert, also zu einem Zeitpunkt, wo du noch gar keine Kontrolle über dein Programm hast. Demnach ist ein Zugriff immer sicher (es sei denn du hast zwei statische Objekte, die gegenseitig aufeinander zugreifen, da spielt die Reihenfolge der Initialisierung eine Rolle, das Problem heisst static initialization order fiasco).

    1. Ist total latte. Der Prozessor verschiebt den Stackpointer um 4 Byte, wenn i innerhalb des Schleifenkörpers deklariert wird. Zeittechnisch merkt die CPU das nichteinmal, du wirst mit keinem Messwerkzeug der Welt einen Unterschied feststellen. Ich bleibe beim Prinzip, Variablen dann anzulegen, wenn sie benötigt werden.


  • SuperMario_Y schrieb:

    Wenn du die Erzeugung deiner statischen Variable in einer Funktion kapselst, erfolgt die Erzeugung beim erstmaligen Aufruf.

    Das ist mir klar.

    SuperMario_Y schrieb:

    Globale Objekte werden vor dem Eintritt in die main() initialisiert.

    Du meinst public static Member Variablen mit globalen V? Ich habe eine private static Variable und einen Public Getter. Der Getter ist global zu erreichen. Dann muß auch die Variable vor Eintritt in main initialisiert werden? Sonst geht es ja nicht.

    SuperMario_Y schrieb:

    Da static-Variablen nicht an Klasseninstanzen (aka Objekte) gebunden sind, erfolgt die Erstellung mit dem ersten Objekt.

    Aber ich kann doch auf die static Variable von einem static Getter zugreifen? Also müssen die Var schon vor dem ersten Objekt init werden.

    Mir geht es darum ob der C++ Standard vorschreibt das die Compiler Herrsteller dort eine Algo anwenden der dafür sorgt das die static Variablen in der richtigen Reihenfolge init werden.

    Konkretes Beispiel: Ich habe ein globale Klasse Settings. Dort sind alle Einstellungen in static Variablen gespeichert. Andere Klassen haben auch static Variablen nd holen sich mit static Gettern der Form GetSetttingX() aus der Settingsklasse die Einstellungen. Es wäre schlecht wenn ein anderer Kompiler die init Reihenfolge vertauscht und der erste Aufruf von GetSetttingX() irgendeinen uninitialisierten Mist zurück gibt.



  • Ein Test ist so schwer?

    #include <iostream>
    
    using namespace std;
    
    class Test
    {
        static Test s_test;
    public:
        Test()
        {
            cout << "Test Constructor" << endl;
        }
        static Test& test1()
        {
            cout << "test1()" << endl;
            static Test t;
            cout << "====" << endl;
            return t;
        }
        static Test& test2()
        {
            cout << "test2()" << endl;
            cout << "====" << endl;
            return s_test;
        }
    };
    
    Test Test::s_test = Test();
    
    int main()
    {
        cout << "Beginne main()" << endl;
        Test::test1();
        Test::test2();
        Test::test1();
    }
    

    Ausgabe:

    Test Constructor
    Beginne main()
    test1()
    Test Constructor
    ====
    test2()
    ====
    test1()
    ====
    

    Schlüsse über Initialisierungszeitpunkt darfst du selber anstellen.



  • Lies hier mal die Abschnitte 10.10 bis 10.16:
    Parashift C++ FAQ


Anmelden zum Antworten