Ordem de avaliação da lista de inicialização do construtor


252

Eu tenho um construtor que leva alguns argumentos. Eu supus que eles foram construídos na ordem listada, mas em um caso parece que eles estavam sendo construídos ao contrário, resultando em um abortamento. Quando eu invertai os argumentos, o programa parou de abortar. Este é um exemplo da sintaxe que estou usando. O problema é que a_ precisa ser inicializado antes de b neste caso. Você pode garantir a ordem de construção?

por exemplo

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

    OtherClass a_;
    AnotherClass b_;
};

6
Você diz que está perguntando sobre argumentos do construtor, mas eles são avaliados antes de você chegar ao construtor e são avaliados em uma ordem não especificada e determinada pelo compilador. Mas você está realmente perguntando sobre a ordem das listas de inicialização, então mudei o título da pergunta para você.
Rob Kennedy

Respostas:


278

Depende da ordem da declaração da variável de membro na classe. Então a_será o primeiro, então b_será o segundo no seu exemplo.


22
De fato, bons compiladores avisarão se você tiver uma ordem diferente na declaração em relação à lista de inicializadores do construtor. Por exemplo, veja -Wreorderem gcc.
Greg Hewgill 7/08/09

236
A razão pela qual eles são construídos na ordem de declaração de membro e não na ordem no construtor é que um pode ter vários construtores, mas há apenas um destruidor. E o destruidor destrói os membros na ordem inversa de construção.
AProgrammer 7/08/09

3
quis dizer ... ordem inversa da declaração. Não é de "construção", o destruidor não pode ver o construtor para saber, pode?
Conrad B #

196

Para citar o padrão, para esclarecimentos:

12.6.2.5

A inicialização deve prosseguir na seguinte ordem:

...

  • Em seguida, os membros de dados não estáticos serão inicializados na ordem em que foram declarados na definição de classe (novamente, independentemente da ordem dos inicializadores de mem).

...


18

A referência padrão para isso agora parece ser 12.6.2, seção 13.3:

(13.3) - Em seguida, os membros de dados não estáticos são inicializados na ordem em que foram declarados na definição de classe (novamente independentemente da ordem dos inicializadores de mem).

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.