Esta es una pregunta simple, pero parece que no puedo encontrar una respuesta definitiva.
Si tenemos la siguiente clase:
class Test
{
...
char testArray[10];
...
};
Cuando creamos una instancia de Test, ¿cuál es el valor predeterminado de testArray?[1]?
Si fuera una matriz local, no se inicializaría.
Si fuera una matriz estática, se inicializaría en 0.
¿Qué hace cuando la matriz es un miembro de la clase?
ben voigt
De la norma, apartado 8.5 [dcl.init]
:
Para inicializar por defecto un objeto de tipo
T
medio:
si
T
es un tipo de clase (posiblemente cv-calificado) (Cláusula 9), el constructor predeterminado paraT
se llama (y la inicialización está mal formada siT
no tiene un constructor predeterminado accesible);si
T
es un tipo de matriz, cada elemento es inicializado por defecto;de lo contrario, no se realiza ninguna inicialización.
también la sección 12.6.2 [class.base.init]
:
En un constructor que no delega, si un miembro de datos no estático o una clase base determinada no está designada por un mem-inicializador-id (incluido el caso en que no haya lista de inicializadores de mem porque el constructor no tiene ctor-inicializador) y la entidad no es una clase base virtual de una clase abstracta (10.4), entonces
- si la entidad es un miembro de datos no estáticos que tiene un inicializador de llave o igualla entidad se inicializa como se especifica en 8.5;
- de lo contrario, si la entidad es un miembro variante (9.5), no se realiza la inicialización;
- de lo contrario, la entidad es inicializado por defecto (8.5).
Entonces, debido a que el tipo de elemento es char
cuando cada elemento es inicializado por defecto, no se realiza ninguna inicialización. Los contenidos se dejan con valores arbitrarios.
A menos, por supuesto, que sea miembro de una instancia de la clase y la instancia tenga una duración de almacenamiento estática. Entonces toda la instancia es inicializado a ceromiembros de la matriz y todo, antes de que comience la ejecución.
-
Entonces, si entiendo correctamente, el valor no se inicializará por defecto a menos que la instancia de la clase Test sea una instancia estática.
– Luciano
13/10/2011 a las 21:15
-
@Luciano: No, se inicializará por defecto si el constructor no especifica un inicializador para él (incluido el constructor implícito que permite la inicialización de agregados). Inicialización predeterminada de un
char[]
es un no-op. Si la instancia tiene una duración de almacenamiento estático, entonces había ceros antes, por lo que después de no operar, sigue siendo cero. En otros casos, lo que quede en la memoria determinará el valor.– Ben Voigt
13/10/2011 a las 21:23
-
@BenVoigt ¿Se puede aplicar esta regla a una matriz estática? si definimos un int local, tendrá un valor aleatorio, pero si definimos un int estático, se establecerá en 0. ¿La matriz estática tiene el mismo comportamiento? se puede encontrar una discusión aquí: stackoverflow.com/q/2091499/440403
– camino
7 junio 2018 a las 14:10
-
@camino: Un local sin inicialización no es un valor “aleatorio”, es un valor indeterminado. La diferencia es importante y realmente estropeó el software de criptografía: research.swtch.com/openssl Los elementos de las matrices estáticas tienen una duración de almacenamiento estática y, por lo tanto, se llenan con ceros. Estar dentro de una matriz u otro agregado no hace ninguna diferencia.
– Ben Voigt
7 junio 2018 a las 14:25
-
@BenVoigtq Ya veo, ¡muchas gracias!
– camino
7 de junio de 2018 a las 14:28
Depende de muchos factores que olvidaste mencionar.
Si tu Test
no tiene un constructor definido por el usuario o su constructor definido por el usuario no hace ningún esfuerzo por inicializar la matriz, y usted declara el objeto de tipo Test
como
Test test; // no initializer supplied
entonces se comportará exactamente de la misma manera que describiste anteriormente. Para un objeto automático (local), el contenido de la matriz seguirá siendo impredecible. Para un objeto estático, se garantiza que el contenido es cero.
Si su clase tiene un constructor definido por el usuario, entonces todo dependerá de lo que haga el constructor. Nuevamente, tenga en cuenta que los objetos estáticos siempre se inicializan en cero antes de que cualquier constructor tenga la oportunidad de hacer algo.
Si su clase es un agregado, entonces el contenido podría depender del inicializador agregado que proporcionó en la declaración del objeto. Por ejemplo
Test test = {};
inicializará a cero la matriz incluso para un objeto automático (local).
-
Y si
testArray()
se llama dentro de la lista de inicialización del constructor, cada elemento de la matriz se inicializará con un valor (lo que significa que se establecerá en 0 para este caso particular)– K-ballo
13/10/2011 a las 21:01
-
Ninguno de estos casos es una inicialización predeterminada. La pregunta pregunta qué sucede durante la inicialización predeterminada.
– Ben Voigt
13/10/2011 a las 21:09
-
@Ben Voigt: Aparentemente, la pregunta hace un mal uso del término “inicialización predeterminada”. Ocurre con bastante frecuencia cuando las personas asumen que si no hacen nada en absoluto, se produce algún tipo de “inicialización predeterminada”. En realidad, la “inicialización predeterminada” en C++ significa algo diferente. Es por eso que no restrinjo la respuesta a “inicialización predeterminada”.
– AnT apoya a Rusia
13/10/2011 a las 21:34
Creo que si no lo inicializa cuando lo declara, puede configurarse en cualquier cosa. A veces es una dirección o un valor de aspecto aleatorio.
La mejor práctica es inicializar después de declarar.
Depende del resto de la definición de la clase, incluida la definición de cualquier constructor y, potencialmente, de cómo se instancia la instancia de la clase. Muestra más código.
–CB Bailey
13/10/2011 a las 20:55
¿Qué quiere decir con “miembro de la clase”? El ejemplo
testArray
ha mostrado, en C++, pertenece a instancias, no a la clase. Para que pertenezca a la clase necesitarías hacerlostatic
y definirlo en otro lugar.– Karl Knechtel
13/10/2011 a las 21:03
@KarlKnechtel: Luciano está usando el término correctamente.
testArray
es un miembro de datos no estático de la clase. “Los miembros de una clase son miembros de datos, funciones de miembros (9.3), tipos anidados y enumeradores. Los miembros de datos y las funciones de miembros son estáticos o no estáticos; consulte 9.4”.– Ben Voigt
13/10/2011 a las 21:06
Charles: suponga que el constructor de Test no asigna valores a testArray.
– Luciano
13/10/2011 a las 21:07
@CharlesBailey: No realmente. Si un constructor proporciona un inicializador, entonces no sería inicializado por defectosino “¿Qué constituye inicialización por defecto para un miembro de la matriz?” sigue siendo una pregunta válida.
– Ben Voigt
13/10/2011 a las 21:07