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_;
};
Matt
quelle
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.

AraK
quelle
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).

...

GManNickG
quelle
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).

Adam Getchell
quelle