Reihenfolge der Inititialisierung in Klasse



  • Hallo,

    ich habe folgendes:

    class Foo
    {
    public:
        Foo();
    private:
        A a;
        B b;
        C c;
    };
    
    Foo::Foo() : b(), a(), c()
    {
        // a is initialized first, then b, then c - NOT b, a, then c!
    }
    

    Der C++11 Standard garantiert dass die Member in der Reihenfolge initialisiert werden, wie in der Header definiert.

    Nun habe ich aber das Problem, dass ich bei einem Programm ein anderes Verhalten habe.

    class Foo
    {
    public:
        Foo();
    private:
        A a;
        B b;
        C c;
    };
    
    Foo::Foo(A& a, B& b, C& c) : a(a), b(CreateData(a.data), c(c)
    {
        // a is initialized first, then b, then c - NOT b, a, then c!
    }
    

    Ich bekomme bei CreateData keine validen Daten für a.data. Es scheint, als ob a noch nicht initialisiert wäre, obwohl das Member a vor dem Member b definiert ist in der Header. 😕



  • benenne die Parameter mal um. könnte sein, dass es dadurch zu Namenskollisionen kommt, die nicht so aufgelöst werden, wie du das gerne hättest



  • Villeicht ist der Copy-c'tor von A fehlerhaft?!

    Zeig ein komplettes minimales Beispiel , an dem man den Fehler nachvollziehen kann.



  • daddy_felix schrieb:

    benenne die Parameter mal um. könnte sein, dass es dadurch zu Namenskollisionen kommt, die nicht so aufgelöst werden, wie du das gerne hättest

    Den gleichen Namen für die Parameter wie für die Membervariablen ist OK. Allerdings wird bei a.data dann der Parameter genommen und nicht die Membervariable. Je nachdem was CreateData macht könnte es dann Probleme geben.



  • Der Standard definiert die Reihenfolge für a, b, c, aber nicht für CreateData(a.data), d.h. die Funktion könnte als erstes aufgerufen werden.



  • Ein komplettes Beispiel ist schwierig, weil der Code hier komplex ist.

    (I)B ist eigentlich ein Interface und CreateData() ist eine freie Funktion, die eine statische Factory-Methode aufruft, die ein Objekt vom Typ B zurückliefert das dem Interface IB entspricht.



  • Achja,

    der Aufruf a(a) ist eigentlich ein Konstruktoraufrug, d.h. a ist eine Klasse, die einen Konstruktor hat, der mit a(a) initialisiert wird. 🙂



  • manni66 schrieb:

    Der Standard definiert die Reihenfolge für a, b, c, aber nicht für CreateData(a.data), d.h. die Funktion könnte als erstes aufgerufen werden.

    Das würde meine Beobachtung erklären. 👍



  • manni66 schrieb:

    Der Standard definiert die Reihenfolge für a, b, c, aber nicht für CreateData(a.data), d.h. die Funktion könnte als erstes aufgerufen werden.

    Dem ist nicht so.
    Jeder Initialisierer ist eine full-expression, und die werden in der bekannten Reihenfolge ausgewertet.



  • manni66 schrieb:

    Der Standard definiert die Reihenfolge für a, b, c, aber nicht für CreateData(a.data), d.h. die Funktion könnte als erstes aufgerufen werden.

    Selbst wenn dem so wäre (ich hab keine Ahnung), spielt das im gezeigten Beispiel keine Rolle weil in der CreateData Funktion der Parameter a verwendet wird und nicht die Membervariable!



  • Furble Wurble schrieb:

    manni66 schrieb:

    Der Standard definiert die Reihenfolge für a, b, c, aber nicht für CreateData(a.data), d.h. die Funktion könnte als erstes aufgerufen werden.

    Dem ist nicht so.
    Jeder Initialisierer ist eine full-expression, und die werden in der bekannten Reihenfolge ausgewertet.

    Stimmt. In C++98 ist es zwar anders formuliert aber effektiv das gleiche.


Anmelden zum Antworten