inicialização matriz
-
06-07-2019 - |
Pergunta
Estou bastante certo de que matrizes de construído em tipos são não inicializado, enquanto matrizes de UDTs são padrão inicializado.
int foo[5]; // will contain junk
Foo foo[5]; // will contain 5 Foo objects that are default initialized
Isso ocorre independentemente da matriz é alocada na pilha ou heap.
No entanto, eu estou achando que é difícil encontrar uma fonte autorizada sobre este assunto. Bjarne afirma que:
"Os membros de matrizes e estruturas são padrão inicializado ou não, dependendo se a matriz ou estrutura é estática" que realmente não me dizem muito.
Eu também tentei encontrar algo no padrão, mas até agora nenhum sem sucesso.
Alguém sabe de uma fonte autorizada para confirmar o acima?
Solução
ISO C ++ 03 é tão autoritário quanto ele ganha:
Um POD-estrutura é uma classe de agregados que não tem membros de dados não-estáticos de não-POD-estrutura tipo, não-POD-união (ou conjunto de tais tipos) ou de referência, e não tem nenhuma atribuição de cópia definido pelo utilizador operador e sem destruição definida pelo utilizador. Da mesma forma, um POD-união é uma união de agregados que não tem membros de dados não-estáticos de não-POD-estrutura tipo, não-POD-união (ou conjunto de tais tipos) ou de referência, e não tem nenhum operador atribuição de cópia definido pelo utilizador e sem destruição definida pelo utilizador. classe A POD é uma classe que é ou um POD-estrutura ou um POD-união.
tipos aritméticos (3.9.1), tipos de enumeração, tipos de ponteiro, e ponteiro de tipos de membros (3.9.2), e versões CV-qualificado destes tipos (3.9.3) são colectivamente chamados tipos escalares. tipos escalares, tipos POD-struct, tipos POD-união (cláusula 9), arrays de tais tipos e versões de cv-qualificado destes tipos (3.9.3) são colectivamente chamados tipos POD.
Para zero inicializar um objeto de meios tipo T:
- se T é um tipo escalar (3,9), o objecto é definido como o valor de 0 (zero) convertido em T;
- Se T é um tipo de classe não-união, cada membro de dados não estático e cada classe de base subobject é inicializado para zero;
- membro de dados se T é um tipo de união, o objeto é primeiro nomeado é inicializado para zero;
- se T é um tipo de matriz, cada elemento é inicializado para zero;
- Se T é um tipo de referência, é realizada nenhuma inicialização.
Para o padrão-inicializar um objeto de meios tipo T:
- Se T é um POD não-tipo de classe (cláusula 9), o construtor padrão para T é chamado (e a inicialização é mal-formado se T não tem nenhum construtor padrão acessível);
- Se T é um tipo de matriz, cada elemento é inicializado-default;
- Caso contrário, o objeto é inicializado para zero.
Para valor-inicializar um objeto de meios tipo T:
- Se T é um tipo de classe (cláusula 9) com um construtor declarado pelo usuário (12.1), então o construtor padrão para T é chamado (e a inicialização é mal-formado se T não tem nenhum construtor padrão acessível);
- Se T é um tipo de classe não-união sem um construtor declarado pelo usuário, em seguida, todos os componentes membro de dados e base de classe non-static de T é de valor inicializado;
- se T é um tipo de matriz, em seguida, cada elemento é de valor inicializado;
- Caso contrário, o objeto é inicializado para zero
Cada objeto de duração de armazenagem estática deve ser zero-inicializado na inicialização do programa antes de qualquer outra inicialização ocorre. [Nota:., Em alguns casos, a inicialização adicional é feito mais tarde]
Um objecto cuja inicializador é um conjunto vazio de parênteses, isto é, (), devem ser de valor inicializado.
Se não inicializador é especificado para um objeto, e o objecto é de (possivelmente cv-qualificado) POD não-tipo de classe (ou matriz dos mesmos), o objecto deve ser inicializado-padrão; se o objeto é do tipo const qualificado, o tipo de classe subjacente deve ter um construtor padrão declarada pelo usuário. Caso contrário, se não for especificado inicializador para um objeto não estático, o objecto e os seus sub-objectos, se alguma, têm um valor inicial indeterminado); se o objeto ou qualquer de suas subobjects são do tipo const qualificado, o programa está mal-formado.
Para o seu exemplo, int
é definitivamente um tipo POD (é um tipo de aritmética), e, portanto, um local ou campo de tipo int
, na ausência de initializer, terá um valor indeterminado. Para Foo
, isso depende de como ele é definido - a grosso modo, se ele não tem um construtor, e todos os seus membros são de tipos POD, em seguida, ele próprio é um tipo POD, e nenhuma inicialização ocorre também. Caso contrário, o construtor padrão é chamado. Mesmo assim, isso não significa que membros são inicializados - regras são recursiva, para que os membros do POD do tipo não-POD não será inicializado a menos que o construtor desse tipo faz especificamente que (em seu inicializador lista).
As variáveis ??estáticas e campos em todos os casos ser zero-inicializado. Note que isso se aplica a não-PODs também -. O que significa que uma variável estática de um tipo de classe é a garantia de ter todos os campos de forma recursiva definida para (T)0
mesmo antes de suas execuções construtor
Um truque útil para default-inicializar qualquer tipo POD agregada é usar {}
em initializer - nota que trabalha com estruturas, bem como matrizes:
char s[10] = {}; // all elements default-initialized
Foo foo = {}; // all fields recursively default-initialized
Outras dicas
Ele diz no C ++ padrão, em 8.5.9:
Se nenhum inicializador é especificado para um objeto, e o objecto é de (possivelmente não-POD tipo de classe cv-qualificado) (ou matriz dos mesmos), o objecto será default-inicializado; Se o objecto está de tipo const-qualificado, o tipo de classe subjacente devem ter um user-declarada construtor padrão. Caso contrário, se não initializer é especificado por um objecto que não seja estático, o objeto e seus sub-objetos, se houver, tem um valor inicial indeterminado.
"Os membros de matrizes e estruturas são padrão inicializado ou não, dependendo se a matriz ou estrutura é estática"
Esta é autoritário, embora pudesse ser mais claro:
- Arrays e estruturas declarados como
static
são inicializados com zeros. - matrizes e estruturas de locais tipos built-in ( i. tipos que não têm construtores) não são inicializados.