¿Qué significan las siguientes frases en C++: zero-, default- and value-initialization?
c++-faq (2)
¿Qué significan las siguientes frases en C ++?
cero inicialización,
inicialización predeterminada, y
inicialización de valor
¿Qué debería saber un desarrollador de C ++ sobre ellos?
Algo que debemos tener en cuenta es que la ''inicialización del valor'' es nueva con el estándar C ++ 2003; no existe en el estándar original de 1998 (creo que podría ser la única diferencia que sea más que una aclaración). Ver la respuesta de Kirill V. Lyadvinsky para las definiciones directamente del estándar.
Consulte esta respuesta anterior sobre el comportamiento del operator new
para obtener detalles sobre el comportamiento diferente de este tipo de inicialización y cuándo se activan (y cuando difieren de c ++ 98 a C ++ 03):
El punto principal de la respuesta es:
A veces la memoria devuelta por el nuevo operador se inicializará, y algunas veces no dependerá de si el tipo que estás renovando es un POD, o si es una clase que contiene miembros POD y está usando un constructor predeterminado generado por el compilador .
- En C ++ 1998 hay 2 tipos de inicialización: cero y por defecto
- En C ++ 2003, se agregó un tercer tipo de inicialización, inicialización de valor.
Por decir lo menos, es bastante complejo y cuando los diferentes métodos entran en juego son sutiles.
Una cosa a tener en cuenta es que MSVC sigue las reglas de C ++ 98, incluso en VS 2008 (VC 9 o cl.exe versión 15.x).
El siguiente fragmento muestra que MSVC y Digital Mars siguen las reglas de C ++ 98, mientras que GCC 3.4.5 y Comeau siguen las reglas de C ++ 03:
#include <stdio.h>
#include <string.h>
#include <new>
struct A { int m; }; // POD
struct B { ~B(); int m; }; // non-POD, compiler generated default ctor
struct C { C() : m() {}; ~C(); int m; }; // non-POD, default-initialising m
int main()
{
char buf[sizeof(B)];
memset( buf, 0x5a, sizeof( buf));
// use placement new on the memset''ed buffer to make sure
// if we see a zero result it''s due to an explicit
// value initialization
B* pB = new(buf) B(); //C++98 rules - pB->m is uninitialized
//C++03 rules - pB->m is set to 0
printf( "m is %d/n", pB->m);
return 0;
}
C ++ 03 Estándar 8.5 / 5:
Inicializar 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-unión, cada miembro de datos no estático y cada subobjeto de clase base tiene cero inicialización;
- si T es un tipo de unión, el primer miembro de datos con nombre del objeto se inicializa en cero;
- si T es un tipo de matriz, cada elemento tiene cero inicialización;
- 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 no POD (cláusula 9), se llama al constructor predeterminado para T (y la inicialización está mal formada si T no tiene un constructor por defecto accesible);
- si T es un tipo de matriz, cada elemento se inicializa por defecto;
- de lo contrario, el objeto tiene cero inicialización.Valorizar-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), entonces se llama al constructor predeterminado para T (y la inicialización está mal formada si T no tiene un constructor por defecto accesible);
- si T es un tipo de clase no sindical sin un constructor declarado por el usuario, entonces cada componente de datos no estáticos y 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 tiene cero inicializaciónUn programa que requiere inicialización por defecto o inicialización de valor de una entidad de tipo de referencia está mal formado. Si T es un tipo calificado para cv, la versión cv no calificada de T se utiliza para estas definiciones de inicialización cero, inicialización predeterminada e inicialización de valor.