Kolejność oceny listy inicjalizacyjnej konstruktora

252

Mam konstruktora, który przyjmuje pewne argumenty. Zakładałem, że zostały zbudowane w podanej kolejności, ale w jednym przypadku wygląda na to, że zostały wykonane w odwrotnej kolejności, co spowodowało przerwanie. Kiedy odwróciłem argumenty, program przestał przerywać. To jest przykład składni, której używam. Chodzi o to, że w tym przypadku należy zainicjować a_ przed b_. Czy możesz zagwarantować kolejność budowy?

na przykład

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

    OtherClass a_;
    AnotherClass b_;
};
Matt
źródło
6
Mówisz, że pytasz o argumenty konstruktora, ale są one sprawdzane, zanim dotrzesz do konstruktora, i są oceniane w nieokreślonej, określonej przez kompilator kolejności. Ale tak naprawdę pytasz o kolejność list inicjalizacyjnych, więc zmieniłem dla ciebie tytuł pytania.
Rob Kennedy

Odpowiedzi:

278

Zależy to od kolejności deklaracji zmiennej składowej w klasie. Tak a_będzie pierwszy, a następnie b_drugi w twoim przykładzie.

ARAK
źródło
22
W rzeczywistości dobre kompilatory będą ostrzegały, jeśli deklaracja ma inną kolejność niż lista inicjalizująca konstruktora. Na przykład zobacz -Wreorderw gcc.
Greg Hewgill,
236
Powodem, dla którego są one konstruowane w porządku deklaracji elementu, a nie w porządku w konstruktorze, jest to, że można mieć kilka konstruktorów, ale istnieje tylko jeden destruktor. I destruktor niszczy członków w kolejności budowy.
AProgrammer
3
czy mieliśmy na myśli ... odwrotna kolejność deklaracji. Nie z „konstrukcji”, destruktor nie może zajrzeć do konstruktora, aby wiedzieć, prawda?
Conrad B
196

Cytując standard, w celu wyjaśnienia:

12.6.2.5

Inicjalizacja przebiega w następującej kolejności:

...

  • Następnie elementy danych niestatycznych powinny być inicjowane w kolejności, w jakiej zostały zadeklarowane w definicji klasy (ponownie bez względu na kolejność inicjatorów pamięci).

...

GManNickG
źródło
18

Norma referencyjna dla tego teraz wydaje się być 12.6.2 sekcja 13.3:

(13.3) - Następnie elementy danych niestatycznych są inicjowane w kolejności, w jakiej zostały zadeklarowane w definicji klasy (ponownie bez względu na kolejność inicjatorów pamięci).

Adam Getchell
źródło