¿Qué significan las siguientes frases en C++?
-
inicialización cero,
-
inicialización por defecto, y
-
valor-inicialización
¿Qué debe saber un desarrollador de C++ sobre ellos?
Cuenta
¿Qué significan las siguientes frases en C++?
inicialización cero,
inicialización por defecto, y
valor-inicialización
¿Qué debe saber un desarrollador de C++ sobre ellos?
C++03 Estándar 8.5/5:
Para cero inicializar 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 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 se inicializa en cero;
— 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 que no es POD (cláusula 9), se llama al constructor predeterminado para T (y la inicialización está mal formada si T no tiene un constructor predeterminado accesible);
— si T es un tipo de matriz, cada elemento se inicializa por defecto;
— de lo contrario, el objeto se inicializa a cero.Para inicializar valor 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 predeterminado accesible);
— si T es un tipo de clase no unión sin un constructor declarado por el usuario, entonces cada miembro de datos no estático y componente de clase base de T se inicializa con valor;
— si T es un tipo de matriz, entonces cada elemento se inicializa con un valor;
— de lo contrario, el objeto se inicializa a ceroUn programa que solicita la inicialización predeterminada o la inicialización de valor de una entidad de tipo de referencia está mal formado. Si T es un tipo calificado cv, la versión no calificada cv de T se utiliza para estas definiciones de inicialización cero, inicialización predeterminada e inicialización de valor.
Esto podría estar desactualizado para C++ 11. cppreference.com establece que la inicialización predeterminada no miembros de inicialización cero (solo la inicialización de valor lo hace).
– Alexei Sholik
9 de julio de 2013 a las 12:05
@android plantea un punto importante, que no veo respondido en ningún otro lugar, por lo que hice una nueva pregunta. stackoverflow.com/questions/22233148/…
– Adrián McCarthy
06/03/2014 a las 18:40
miguel rebabas
Una cosa a tener en cuenta es que la ‘inicialización de 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). Consulte la respuesta de Kirill V. Lyadvinsky para conocer las definiciones directamente del estándar.
Ver 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 se activan (y cuándo difieren de c ++ 98 a C ++ 03):
El punto principal de la respuesta es:
A veces, la memoria devuelta por el operador new se inicializará y, a veces, no, dependiendo de si el tipo que está renovando es un POD o si es una clase que contiene miembros de POD y usa 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 acción 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;
}
No es que importe para int
pero m()
en la tercera línea el valor inicializa m. Importante si cambias int m;
para B m;
. 🙂
– Johannes Schaub – litb
23 de octubre de 2009 a las 14:46
Derecha – A
y C
no se usan en este ejemplo (se transfieren de la otra respuesta vinculada). Aunque C++98 y C++03 utilizan una terminología diferente al describir cómo A
y C
se construyen, el resultado es el mismo en ambos estándares. Solamente struct B
da como resultado un comportamiento diferente.
– Michael Burr
23 de octubre de 2009 a las 14:55
lo que quise decir es que si cambias C a struct C { C() : m() {}; ~C(); B m; };
entonces tendrás m.m
sea 0. Pero si se inicializara por defecto m
como dices que hace C++03, entonces m.m
no se inicializaría como en C++98.
– Johannes Schaub – litb
27 de septiembre de 2010 a las 14:44
Comentarios interesantes adicionales sobre el manejo de MSVC de esta característica: stackoverflow.com/questions/3931312/…
–Brent Bradburn
26 de julio de 2011 a las 21:45
g++ 4.4.7 20120313 para Red Hat 4.4.7-18 inicializa m a 0 con su ejemplo (compilando con -std=c++98).
– Jean
27 de abril de 2018 a las 8:57
Esto está relacionado con (pero no es idéntico a) stackoverflow.com/questions/620137/…
–Steve Jessop
7 de diciembre de 2010 a las 17:20
¡Hay más! La lista completa de inicializaciones: valor, directo, copia, lista (nueva introducción de C++ 11), agregado, referencia, cero, constante y predeterminado; es.cppreference.com/w/cpp/language/initialization enumera todos ellos con ejemplos 🙂
– leyendas2k
7 mayo 2013 a las 14:29