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_;
};

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.


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

...


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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.