Snapshot s;// receives no initializationSnapshot s ={};// value initializes all members
El segundo hará que todos los miembros sean cero, el primero los deja en valores no especificados. Tenga en cuenta que es recursivo:
structParent{Snapshot s;};Parent p;// receives no initializationParent p ={};// value initializes all members
El segundo hará p.s.{x,y}cero. No puede usar estas listas de inicializadores agregados si tiene constructores en su estructura. Si ese es el caso, deberá agregar la inicialización adecuada a esos constructores
structSnapshot{int x;double y;Snapshot():x(0),y(0){}// other ctors / functions...};
Inicializará tanto x como y a 0. Tenga en cuenta que puede usar x(), y()para inicializar sin tener en cuenta su tipo: esa es la inicialización del valor, y generalmente produce un valor inicial adecuado (0 para int, 0.0 para doble, llamando al constructor predeterminado para el usuario definido tipos que tienen constructores declarados por el usuario, ...). Esto es importante especialmente si su estructura es una plantilla.
Esto produce muchas advertencias en mi compilador.
River-Claire Williamson
1
Roger: Intente usar la estructura con nombre en el inicializador, eso es lo que hago y no recibo ninguna advertencia en VC 2012: Snapshot s = Snapshot ();
Kit10
@Johannes Schaub - litb ¿Funcionará Snapshot s = {};para los miembros que no son POD (por ponerlos a cero)?
ontherocks
2
C ++ 11 ahora le permite inicializarlos en la definición de la estructura o clase, de este modo: struct Snapshot {double x {0}; // con llaves int y = 0; // o simplemente el estilo de la vieja escuela 'por asignación' que también es realmente inicialización};
ikku100
1
Es "Instantánea s = {};" parte de la norma?
Stefan
41
No, no son 0 por defecto. La forma más sencilla de garantizar que todos los valores o predeterminados a 0 es definir un constructor
Snapshot(): x(0), y(0){}
Esto asegura que todos los usos de Snapshot tendrán valores inicializados.
La desventaja es que la estructura ya no es un tipo POD, porque tiene un constructor. Eso interrumpirá algunas operaciones, como escribirlo en un archivo temporal.
finnw 01 de
16
@finnw: C ++ 11 corrige esto, aunque la estructura no es POD, es "diseño estándar".
Ben Voigt
20
En general, no. Sin embargo, una estructura declarada como alcance de archivo o estática en una función / se inicializará a 0 (al igual que todas las demás variables de esos ámbitos):
int x;// 0int y =42;// 42struct{int a, b;} foo;// 0, 0void foo(){struct{int a, b;} bar;// undefinedstaticstruct{int c, d;} quux;// 0, 0}
Eso realmente no es una suposición segura. no debe confiar en el valor de nada que no haya inicializado
Hasturkun
24
Los objetos de duración de almacenamiento estático siempre se inicializan a cero; consulte stackoverflow.com/questions/60653/… para obtener una cita del estándar. Si este es un buen estilo es otra cuestión.
bdonlan 01 de
12
Con POD también puedes escribir
Snapshot s ={};
No debe usar memset en C ++, memset tiene el inconveniente de que si hay un no POD en la estructura, lo destruirá.
o así:
struct init
{template<typename T>operator T *(){returnnew T();}};Snapshot* s = init();
@Andy Most Vexing Parse convierte cosas que se parecen a las herramientas normales ( SomeType foo();es la típica, aunque puede suceder con otras) en definiciones de funciones (en ese caso, una función fooque regresa SomeType). Perdón por el necro, pero si alguien más se encuentra con esto, pensé que respondería.
Financia la demanda de Mónica el
8
En C ++, use constructores sin argumentos. En C no puede tener constructores, así que use uno memseto la solución interesante: inicializadores designados:
Creo que esto es C, no C ++. No se compilará en algunos compiladores de C ++. Experimenté la falla de compilación bajo Cygwin o MinGW.
jww
3
Creo que la respuesta correcta es que sus valores no están definidos. A menudo, se inicializan a 0 cuando se ejecutan versiones de depuración del código. Este no suele ser el caso cuando se ejecutan versiones de lanzamiento.
Lo mismo vale para el doble; all-bits-zero no es necesariamente 0.0. Sin embargo, puede verificar si tiene dobles IEEE754, en cuyo caso debe funcionar.
MSalters
1
Mueva los miembros del pod a una clase base para acortar su lista de inicializadores:
Respuestas:
No son nulos si no inicializa la estructura.
El segundo hará que todos los miembros sean cero, el primero los deja en valores no especificados. Tenga en cuenta que es recursivo:
El segundo hará
p.s.{x,y}
cero. No puede usar estas listas de inicializadores agregados si tiene constructores en su estructura. Si ese es el caso, deberá agregar la inicialización adecuada a esos constructoresInicializará tanto x como y a 0. Tenga en cuenta que puede usar
x(), y()
para inicializar sin tener en cuenta su tipo: esa es la inicialización del valor, y generalmente produce un valor inicial adecuado (0 para int, 0.0 para doble, llamando al constructor predeterminado para el usuario definido tipos que tienen constructores declarados por el usuario, ...). Esto es importante especialmente si su estructura es una plantilla.fuente
Snapshot s = {};
para los miembros que no son POD (por ponerlos a cero)?No, no son 0 por defecto. La forma más sencilla de garantizar que todos los valores o predeterminados a 0 es definir un constructor
Esto asegura que todos los usos de Snapshot tendrán valores inicializados.
fuente
En general, no. Sin embargo, una estructura declarada como alcance de archivo o estática en una función / se inicializará a 0 (al igual que todas las demás variables de esos ámbitos):
fuente
Con POD también puedes escribir
No debe usar memset en C ++, memset tiene el inconveniente de que si hay un no POD en la estructura, lo destruirá.
o así:
fuente
SomeType foo();
es la típica, aunque puede suceder con otras) en definiciones de funciones (en ese caso, una funciónfoo
que regresaSomeType
). Perdón por el necro, pero si alguien más se encuentra con esto, pensé que respondería.En C ++, use constructores sin argumentos. En C no puede tener constructores, así que use uno
memset
o la solución interesante: inicializadores designados:fuente
Creo que la respuesta correcta es que sus valores no están definidos. A menudo, se inicializan a 0 cuando se ejecutan versiones de depuración del código. Este no suele ser el caso cuando se ejecutan versiones de lanzamiento.
fuente
0
en esos lugares en la memoria. ¡Esto no es lo mismo que la inicialización!Dado que este es un POD (esencialmente una estructura C), hay poco daño en inicializarlo de la manera C:
o de manera similar
Sin embargo, no iría tan lejos como para usarlo
calloc()
en un programa C ++.fuente
Mueva los miembros del pod a una clase base para acortar su lista de inicializadores:
fuente