c++ - microsoft - visual studio installer
¿Puede un miembro struct ser zero-init desde la lista de inicializadores del constructor sin llamar a memset? (3)
Digamos que tengo la siguiente declaración de estructura (estructura simple sin constructor).
struct Foo
{
int x;
int y;
int z;
char szData[DATA_SIZE];
};
Ahora supongamos que esta estructura es miembro de una clase de C ++ de la siguiente manera:
class CFoobar
{
Foo _foo;
public:
CFoobar();
};
Si declaro el constructor de CFoobar de la siguiente manera:
CFoobar::CFoobar()
{
printf("_foo = {%d, %d, %d}/n", _foo.x, _foo.y,_foo.z);
for (int x = 0; x < 100; x++)
printf("%d/n", _foo.szData[x]);
}
Como era de esperar, cuando se ejecuta el constructor de CFoobar, se imprimen los datos basura. Obviamente, la solución más sencilla es memset o ZeroMemory & _foo. Es lo que siempre he hecho ...
Sin embargo, me di cuenta de que si agrego _foo a la lista de inicialización del constructor sin parámetros de la siguiente manera:
CFoobar::CFoobar()
: _foo()
{
Que esto parece poner a cero las variables miembro de _foo. Al menos ese fue el caso con g ++ en Linux.
Ahora aquí está mi pregunta: ¿Es este C ++ estándar, o es este comportamiento específico del compilador?
Si es un comportamiento estándar, ¿alguien puede citarme una referencia de una fuente oficial? ¿Algún "truco" con respecto al comportamiento implícito de inicio cero con estructuras y clases más complicadas?
Es el equivalente de float foo = float();
Va a poner a cero el objeto, incluso si la representación del valor no es todo-bits-cero. Es decir, es incluso mejor que memset()
.
Me resulta difícil leer el estándar, pero lo encontré, creo:
Valorizar-inicializar un objeto de tipo T significa:
si T es un tipo de clase no sindical sin un constructor declarado por el usuario, entonces cada miembro de datos no estáticos y un componente de clase base de T es inicialización de valor inicializada por valor para tal objeto de clase puede implementarse inicializando cero el objeto y luego llamar al constructor predeterminado.
Sección 8.5
Sí, esto es comportamiento definido de acuerdo con el estándar. 12.6.2 [class.base.init] / 3: "si la lista de expresiones del mem-initializer se omite, la clase base o el subobjeto miembro se inicializa en valor ".
Tenga en cuenta, sin embargo, si Foo
no era un tipo POD, pero aún no tenía un constructor declarado por el usuario (por ejemplo, tenía un tipo std::string
), entonces algunos compiladores muy populares no lo inicializarían correctamente.
Todos los compiladores que conozco realizan correctamente la inicialización de valor de los miembros POD cuando usa ()
como inicializador en una lista de inicializadores de constructor.