¿Qué significan las siguientes frases en C ++:
inicialización cero,
inicialización predeterminada y
inicialización de valor
¿Qué debe saber un desarrollador de C ++ sobre ellos?
¿Qué significan las siguientes frases en C ++:
inicialización cero,
inicialización predeterminada y
inicialización de valor
¿Qué debe saber un desarrollador de C ++ sobre ellos?
Respuestas:
Una cosa a 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 es 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 de operator new
para obtener detalles sobre el comportamiento diferente de este tipo de inicialización y cuándo entran en acción (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 a veces no dependerá de si el tipo que está renovando es un POD, o si es una clase que contiene miembros de POD y está utilizando un constructor predeterminado generado por el compilador .
- En C ++ 1998 hay 2 tipos de inicialización: cero y predeterminado
- En C ++ 2003, un tercer tipo de inicialización, se agregó la 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 <cstdio>
#include <cstring>
#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)];
std::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
std::printf( "m is %d\n", pB->m);
return 0;
}
int
, pero m()
en la tercera línea el valor inicializa m. Importante si cambias int m;
a B m;
. :)
A
y C
no se usan en este ejemplo (se transfieren de la otra respuesta vinculada). Aunque C ++ 98 y C ++ 03 usan una terminología diferente al describir cómo A
y C
se construyen, el resultado es el mismo en ambos estándares. Solo struct B
da como resultado un comportamiento diferente.
struct C { C() : m() {}; ~C(); B m; };
, entonces tendrá m.m
0. Pero si se inicializa por defecto m
como dice C ++ 03, entonces m.m
no se inicializaría como en C ++ 98.
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 sindical, cada miembro de datos no estático y cada subobjeto de clase base se inicializa en cero;
- si T es un tipo de unión, el primer miembro de datos nombrado del objeto se inicializa 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 default-inicializar un objeto de medios de tipo T:
- si T es a-POD no tipo de clase (cláusula 9), el constructor predeterminado de T se llama (y está mal formada la inicialización si T no tiene 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 valor-inicializar un objeto de medios de tipo T:
- si T es un tipo de clase (cláusula 9) con un constructor-declarado de usuario (12.1), entonces el constructor predeterminado de T se llama (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 ceroUn programa que requiere inicialización predeterminada 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 no calificada de cv de T se usa para estas definiciones de inicialización cero, inicialización predeterminada e inicialización de valor.