Bewertungsreihenfolge der Konstruktorinitialisierungsliste


252

Ich habe einen Konstruktor, der einige Argumente akzeptiert. Ich hatte angenommen, dass sie in der angegebenen Reihenfolge konstruiert wurden, aber in einem Fall scheint es, dass sie in umgekehrter Reihenfolge konstruiert wurden, was zu einem Abbruch führte. Als ich die Argumente umkehrte, hörte das Programm auf abzubrechen. Dies ist ein Beispiel für die von mir verwendete Syntax. Die Sache ist, dass a_ in diesem Fall vor b_ initialisiert werden muss. Können Sie die Bauordnung garantieren?

z.B

class A
{
  public:
    A(OtherClass o, string x, int y) :
      a_(o), b_(a_, x, y) { }

    OtherClass a_;
    AnotherClass b_;
};

6
Sie sagen, Sie fragen nach Konstruktorargumenten, aber sie werden ausgewertet, bevor Sie den Konstruktor erreichen, und sie werden in einer nicht angegebenen, vom Compiler festgelegten Reihenfolge ausgewertet. Aber Sie fragen wirklich nach der Reihenfolge der Initialisierungslisten, deshalb habe ich den Fragentitel für Sie geändert.
Rob Kennedy

Antworten:


278

Dies hängt von der Reihenfolge der Deklaration der Mitgliedsvariablen in der Klasse ab. So a_wird der erste sein, dann b_wird der zweite in Ihrem Beispiel sein.


22
Tatsächlich warnen gute Compiler, wenn Sie in der Deklaration eine andere Reihenfolge als in der Liste der Konstruktorinitialisierer haben. Siehe zum Beispiel -Wreorderin gcc.
Greg Hewgill

236
Der Grund, aus dem sie in der Reihenfolge der Elementdeklaration und nicht in der Reihenfolge im Konstruktor erstellt werden, besteht darin, dass man mehrere Konstruktoren haben kann, aber es gibt nur einen Destruktor. Und der Zerstörer zerstört die Mitglieder in der umgekehrten Reihenfolge der Konstruktion.
AProgrammer

3
Meinten wir ... umgekehrte Reihenfolge der Erklärung. Nicht von "Konstruktion", kann der Destruktor unmöglich in den Konstruktor sehen, um zu wissen, oder?
Conrad B

196

Um den Standard zur Verdeutlichung zu zitieren:

12.6.2.5

Die Initialisierung erfolgt in der folgenden Reihenfolge:

...

  • Dann werden nicht statische Datenelemente in der Reihenfolge initialisiert, in der sie in der Klassendefinition deklariert wurden (wiederum unabhängig von der Reihenfolge der Mem-Initialisierer).

...


18

Die Standardreferenz hierfür scheint nun 12.6.2 Abschnitt 13.3 zu sein:

(13.3) - Dann werden nicht statische Datenelemente in der Reihenfolge initialisiert, in der sie in der Klassendefinition deklariert wurden (wiederum unabhängig von der Reihenfolge der Mem-Initialisierer).

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.