Initialization list: field initializer mit Argumenten?



  • Hallo zusammen,

    ich habe eine Codestelle, die ich nicht ganz verstehe:

    class TDataTableBase: public ::xml_schema::Type
    {
    public:
    	TDataTableBase (const TDataTableBase& x, ::xml_schema::Flags f = 0, ::xml_schema::Container* c = 0);
    protected:
        ::xsd::cxx::tree::one< DescriptionType > Description_;
        ::xsd::cxx::tree::one< DataType > Data_;
    };
    
    TDataTableBase::
      TDataTableBase (const TDataTableBase& x,
                      ::xml_schema::Flags f,
                      ::xml_schema::Container* c)
      : ::xml_schema::Type (x, f, c),
        Description_ (x.Description_, f, this),
        Data_ (x.Data_, f, this)
      {
      }
    

    Wie genau muss man die initialization list verstehen? Also das erste Element ::xml_schema::Type ist der Konstruktor der Basisklasse, aber was kommt dann? Description_ und Data_ sind Felder der Klasse, aber warum kann man die mit Argumenten aufrufen?

    Vielen Dank im Voraus für die Hilfe!


  • Mod

    Das sind die Konstruktoren dieser Member. Das ist es, wozu Initialisierungslisten da sind. Ich bin gerade etwas verwirrt, wie du einerseits wissen kannst, was eine Initialisierungsliste ist und wie sie funktioniert, aber andererseits nicht weißt was sie ist und wie sie funktioniert. 😕

    Wenn ich es so schreibe, verstehst du es dann?

    struct foo
    {
      int i;
      std::vector<double> v;
      foo() : i(0), v(123, 1.0) { }
    }
    

    In deinem Beispiel passiert nichts anderes, außer dass am Anfang noch die Basisklasse initialisiert wird (was du ja anscheinend schon verstanden hast)



  • Okay, danke, jetzt verstehe ich das. Ich dachte bisher immer, die Syntax wäre einfach so, also dass wenn man ein Member i initialisieren will, man i( <wert> ) schreibt. Aber wenn ich dich richtig verstehe, ruft man in Wirklichkeit die Konstruktoren der Member auf, nur dass es im einfachen Fall der Copy-Konstruktor ist, wohingegen in meinem Fall ein anderer Konstruktor mit mehreren Parametern aufgerufen wird? Aber ist die Reihenfolge in einer Initialisierungsliste dann festgelegt, also zuerst der Konstruktor der Basisklasse, dann die Member, oder kann man das auch in einer anderen Reihenfolge angeben?


  • Mod

    hejira schrieb:

    Aber wenn ich dich richtig verstehe, ruft man in Wirklichkeit die Konstruktoren der Member auf, nur dass es im einfachen Fall der Copy-Konstruktor ist, wohingegen in meinem Fall ein anderer Konstruktor mit mehreren Parametern aufgerufen wird?

    Ja.

    Aber ist die Reihenfolge in einer Initialisierungsliste dann festgelegt, also zuerst der Konstruktor der Basisklasse, dann die Member, oder kann man das auch in einer anderen Reihenfolge angeben?

    Die Regeln sind:
    1. Die Reihenfolge in der du die Initialisierungsliste schreibst, ist vollkommen schnuppe. Die Liste gibt bloß an, mit welchen Argumenten die Konstruktoren ausgerufen werden, nicht ihre Reihenfolge. Du solltest dich aber an die echte Initialisierungsreihenfolge halten, damit du dich nicht selber verwirrst.
    2. Zuerst werden virtuelle Basisklassen initialisiert, in der Reihenfolge (links nach rechts) wie sie bei der Angabe der Basisklassen stehen
    3. Danach kommen andere Basisklassen, wieder von links nach rechts
    4. Dann kommen (nicht-statische) Member dran. In der Reihenfolge (von oben nach unten) wie sie in der Klassendefinition stehen.
    5. Danach wird der Konstruktor selber ausgeführt

    Das war sehr technisch. Die Regeln zum Merken sind:
    - Zuerst kommen Basisklassen
    - Dann Member von oben nach unten
    - Reihenfolge in der Initialisierungsliste ist egal
    - Die Reihenfolge im Destruktor ist genau umgekehrt



  • Super! Vielen Dank für die kompetente Hilfe. 🙂


  • Mod

    SeppJ schrieb:

    2. Zuerst werden virtuelle Basisklassen initialisiert, in der Reihenfolge (links nach rechts) wie sie bei der Angabe der Basisklassen stehen

    Kleine Präzisierung: es werden alle virtuellen Basisklassen direkt von vom Konstruktor der am weitestesten abgeleiteten Klasse (also des dynamischen Typs nach Abschluss der Konstruktion) intialisiert, die irgendwo in der Vererbungshierarchie auftauchen (in der Reihenfolge, wie sie bei Tiefensuche auftauchen, jeweils von links nach rechts); auch solche also, die nur indirekt geerbt werden. Ist die Klasse, in der unser Konstruktor sich befindet, dagegen selbst eine Basisklasse, so wird der Teil der Initialisierungliste, der die virtuellen Basisklassen betrifft, übergangen (es werden also auch keine Ausdrücke ausgewertet, die als Argumente für Konstruktion der virtuellen Basen dienen).


Log in to reply