Alterações na ordem de inicialização do construtor
A ordem de inicialização para construtores de classe foi alterado de Managed Extensions for C++ para Visual C++.
Comparação da ordem de inicialização do construtor
Em Managed Extensions for C++, inicialização de construtor ocorreu na seguinte ordem:
O construtor da classe base, se houver, é invocado.
A lista de inicialização da classe é avaliada.
O corpo de código do construtor da classe é executado.
Esta ordem de execução segue as mesmas convenções como na programação do C++ nativa.A nova linguagem Visual C++ prescreve a seguinte ordem de execução de classes CLR:
A lista de inicialização da classe é avaliada.
O construtor da classe base, se houver, é invocado.
O corpo de código do construtor da classe é executado.
Observação que essa alteração se aplica apenas a classes CLR; nativo classes Visual C++ ainda seguem as convenções anteriores.Ambos os casos, essas regras em cascata para cima em toda a cadeia de toda a hierarquia de uma determinada classe.
Considere o seguinte exemplo de código usando Managed Extensions for C++:
__gc class A
{
public:
A() : _n(1)
{
}
protected:
int _n;
};
__gc class B : public A
{
public:
B() : _m(_n)
{
}
private:
int _m;
};
Seguindo a ordem de inicialização do construtor indicadas acima, deveremos ver a seguinte ordem de execução quando novas instâncias da classe B são construídos:
O construtor da classe base A é invocado.O _n membro é inicializado para 1.
A lista de inicialização da classe B é avaliada.O _m membro é inicializado para 1.
Corpo do código da classe B é executado.
Agora considere o mesmo código na novo sintaxe do Visual C++:
ref class A
{
public:
A() : _n(1)
{
}
protected:
int _n;
};
ref class B : A
{
public:
B() : _m(_n)
{
}
private:
int _m;
};
A ordem de execução quando novas instâncias da classe B são construídos sob a nova sintaxe é:
A lista de inicialização da classe B é avaliada.O _m membro é inicializado para 0 (0 é o valor não inicializado o _m membro da classe).
O construtor da classe base A é invocado.O _n membro é inicializado para 1.
Corpo do código da classe B é executado.
Observe que uma sintaxe semelhante produz resultados diferentes para esses exemplos de código.O construtor da classe B depende de um valor de classe base A para inicializar o membro.No entanto, o construtor da classe A ainda não foi invocado.Tal dependência pode ser especialmente perigosa quando a classe herdada depende de uma alocação de memória ou recursos para ocorrer no construtor da classe base.
Isso significa que vai de Managed Extensions for C++ Visual C++ 2010
Em muitos casos as alterações para a ordem de execução dos construtores de classe devem ser transparentes para o programador porque classes base não têm noção do comportamento das classes herdadas.No entanto, como ilustram esses exemplos de código, os construtores de classes herdadas podem ser significativamente afetados quando suas listas de inicialização dependem de valores de membros de classe base.Quando você mover seu código de Managed Extensions for C++ para a nova sintaxe, considere mover tais construções ao corpo do construtor da classe, onde a execução garantida para ocorrer por último.