C++:Construção e de inicialização de ordem garantias
-
22-09-2019 - |
Pergunta
Eu tenho algumas dúvidas sobre a construção e a ordem de inicialização de garantias em C++.Por exemplo, o código a seguir tem quatro classes de X
, Y
, Z
e W
.A função principal instancia um objeto da class X
, que contém um objeto de class Y
, e deriva de class Z
, assim que os construtores será chamado.Além disso, o const char*
parâmetro passado para X
's construtor vai ser implicitamente convertido para um objeto de class W
, então W
's construtor também deve ser chamado.
Quais são as garantias que o padrão de C++ dá a ordem das chamadas para os construtores de cópia?Ou, equivalentemente, o que este programa tem permissão de impressão?
#include <iostream>
class Z {
public:
Z() { std::cout << "Z" << std::endl; }
};
class Y {
public:
Y() { std::cout << "Y" << std::endl; }
};
class W {
public:
W(const char*) { std::cout << "W" << std::endl; }
};
class X : public Z {
public:
X(const W&) { std::cout << "X" << std::endl; }
private:
Y y;
};
int main(int, char*[]) {
X x("x");
return 0;
}
editar:Isso está correto?
W |
/ \ |
Z Y |
\ / |
X V
Solução
Em todas as classes de construção de ordem é a garantia de:classes base, conforme especificado a partir da esquerda para a direita, seguido por variáveis de membro na ordem declarada na definição de classe.Um construtor da classe do corpo é executada uma vez todas as suas bases e membros' construções concluídas.
No seu exemplo X
é derivado a partir de Z
e contém Y
de modo que o Z
objecto de base é construída em primeiro lugar, o Y
membro y
, e , em seguida, a construção do X
conclui-se com a execução de X
's construtor de corpo.
Temporário W
é necessária para passar para o construtor de X
, então ele é construído antes da construção do x
começa e vai ser destruída, uma vez que a inicialização do x
conclui.
Assim, o programa deve imprimir:
W
Z
Y
X
Outras dicas
1) Primeiro de tudo, é necessário calcular os argumentos.
2) Então as classes base são construídas.
3) Em seguida, os membros são construídos na ordem de aparência na declaração da classe.
4) Então o construtor de x é chamado
- O objeto W será construído antes que o construtor para X seja chamado.
- Z, como uma classe base de X, será inicializado antes dos membros de X.
- Y será infitalizado durante a inicialização do membro
- O construtor de X será executado.
Para expandir a resposta de Charles Bailey, as regras mudam quando suas classes base são herdadas virtualmente. Sempre esqueço qual é a ordem, o site da IBM diz que as bases virtuais são inicializadas primeiro, mas nunca encontrei um caso em que é realmente mais do que curiosidades.
Para resumir essas são as regras:
- Argumentos, tirados da direita para a esquerda
uma. Mais certo
b. 2º da direita - Classe base
- Base virtual
- Classes base da esquerda para a direita
- Membros em ordem de declaração na aula
- Construtor de Class