Pregunta

Estoy bastante seguro de que las matrices de tipos integrados están unitarias, mientras que las matrices de UDT están inicializadas por defecto.

int foo [5]; // contendrá basura
Foo foo [5]; // contendrá 5 objetos Foo que están inicializados por defecto

Esto ocurre independientemente de si la matriz está asignada en la pila o en el montón.

Sin embargo, me resulta difícil encontrar una fuente autorizada sobre esto. Bjarne afirma que:

" Los miembros de matrices y estructuras se inicializan por defecto o no, dependiendo de si la matriz o estructura es estática " que realmente no me dice demasiado.

También he tratado de encontrar algo en el estándar, pero hasta ahora no ha sido posible.

¿Alguien sabe de una fuente autorizada para confirmar lo anterior?

¿Fue útil?

Solución

ISO C ++ 03 es tan autoritario como se pone:

  

Un POD-struct es una clase agregada que no tiene miembros de datos no estáticos de tipo non-POD-struct, non-POD-union (o matriz de tales tipos) o referencia, y no tiene una asignación de copia definida por el usuario operador y sin destructor definido por el usuario. Del mismo modo, una unión POD es una unión agregada que no tiene miembros de datos no estáticos de tipo non-POD-struct, non-POD-union (o matriz de tales tipos) o referencia, y no tiene operador de asignación de copia definido por el usuario y sin destructor definido por el usuario. Una clase POD es una clase que es una estructura POD o una unión POD.

     

Los tipos aritméticos (3.9.1), los tipos de enumeración, los tipos de puntero y los tipos de puntero a miembro (3.9.2) y las versiones calificadas por cv de estos tipos (3.9.3) se denominan colectivamente tipos escalares. Los tipos escalares, los tipos de estructura POD, los tipos de unión POD (cláusula 9), las matrices de tales tipos y las versiones calificadas por cv de estos tipos (3.9.3) se denominan colectivamente tipos POD.

     

Poner a cero un objeto de tipo T significa:

     
      
  • si T es un tipo escalar (3.9), el objeto se establece en el valor de 0 (cero) convertido a T;
  •   
  • si T es un tipo de clase no sindical, cada miembro de datos no estático y cada clase base   subobject tiene inicialización cero;
  •   
  • si T es un tipo de unión, el primer miembro de datos nombrado del objeto está inicializado en cero;
  •   
  • si T es un tipo de matriz, cada elemento tiene inicialización cero;
  •   
  • si T es un tipo de referencia, no se realiza ninguna inicialización.
  •   
     

Para inicializar por defecto un objeto de tipo T significa:

     
      
  • si T es un tipo de clase que no es POD (cláusula 9), se llama al constructor predeterminado para T (y la inicialización está mal formada si T no tiene un constructor predeterminado accesible);
  •   
  • si T es un tipo de matriz, cada elemento se inicializa por defecto;
  •   
  • de lo contrario, el objeto está inicializado en cero.
  •   
     

Para inicializar un objeto de tipo T significa:

     
      
  • si T es un tipo de clase (cláusula 9) con un constructor declarado por el usuario (12.1), se llama al constructor predeterminado para T (y la inicialización está mal formada si T no tiene un constructor predeterminado accesible);
  •   
  • si T es un tipo de clase sin unión sin un constructor declarado por el usuario, entonces cada miembro de datos no estático y componente de clase base de T tiene un valor inicializado;
  •   
  • si T es un tipo de matriz, entonces cada elemento tiene un valor inicializado;
  •   
  • de lo contrario, el objeto está inicializado en cero
  •   
     

Cada objeto de duración de almacenamiento estático se inicializará en cero al inicio del programa antes de que tenga lugar cualquier otra inicialización. [Nota: en algunos casos, la inicialización adicional se realiza más tarde.]

     

Un objeto cuyo inicializador es un conjunto vacío de paréntesis, es decir, (), se inicializará con valor.

     

Si no se especifica ningún inicializador para un objeto, y el objeto es de tipo (posiblemente calificado por cv) sin clase de POD (o matriz del mismo), el objeto se inicializará por defecto; si el objeto es de tipo calificado const, el tipo de clase subyacente tendrá un constructor predeterminado declarado por el usuario. De lo contrario, si no se especifica ningún inicializador para un objeto no estático, el objeto y sus subobjetos, si los hay, tienen un valor inicial indeterminado); Si el objeto o cualquiera de sus subobjetos son de tipo calificado, el programa está mal formado.

Para su ejemplo, int es definitivamente un tipo POD (es un tipo aritmético) y, por lo tanto, un local o campo de tipo int , en ausencia de inicializador, tendrá un valor indeterminado. Para Foo , esto depende de cómo se defina: en términos generales, si no tiene un constructor y todos sus miembros son de tipo POD, entonces es un tipo de POD y no hay inicialización tiene lugar tampoco. De lo contrario, se llama al constructor predeterminado. Incluso entonces, esto no significa que los miembros se inicialicen: las reglas son recursivas, por lo que los miembros POD de tipo no POD no se inicializarán a menos que el constructor de ese tipo lo haga específicamente (en su inicializador lista).

Las variables y campos estáticos se inicializarán en cero en todos los casos. Tenga en cuenta que esto también se aplica a los que no son POD, lo que significa que se garantiza que una variable estática de un tipo de clase tiene todos los campos recursivamente establecidos en (T) 0 incluso antes de que se ejecute su constructor.

Un truco útil para inicializar por defecto cualquier tipo de POD agregado es utilizar {} en el inicializador; tenga en cuenta que funciona con estructuras y matrices:

char s[10] = {}; // all elements default-initialized
Foo foo = {};    // all fields recursively default-initialized

Otros consejos

Dice en el estándar C ++, en 8.5.9:

  

Si no se especifica un inicializador para un   objeto, y el objeto es de (posiblemente   tipo de clase no POD calificado por cv (o   matriz del mismo), el objeto será   inicializado por defecto; si el objeto es   de tipo calificado const, el   el tipo de clase subyacente tendrá un   constructor predeterminado declarado por el usuario.   De lo contrario, si no hay inicializador   especificado para un objeto no estático, el   objeto y sus subobjetos, si los hay,   tener un valor inicial indeterminado.

  

" Los miembros de matrices y estructuras se inicializan por defecto o no, dependiendo de si la matriz o estructura es estática "

Esto tiene autoridad, aunque podría ser más claro:

  • Las matrices y estructuras declaradas como static se inicializan a ceros.
  • Las matrices locales y las estructuras de los tipos incorporados ( es decir, tipos que no tienen constructores) no se inicializan.
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top