Inicialización por defecto
Esta es la inicialización que se realiza cuando una variable se construye sin un inicializador.
Contenido |
[editar] Sintaxis
T objeto ;
|
(1) | ||||||||
new T
|
(2) | ||||||||
[editar] Explicación
La inicialización por defecto se realiza en tres situaciones:
new
sin inicializador o cuando un objeto es creado mediante una expresión con el inicializador que consiste en un par de paréntesis vacío (hasta C++03);Los efectos de la inicialización por defecto son:
- si
T
es un tipo de clase y no un tipo de datos simple (hasta C++11), los constructores se consideran y están sujetos a la resolución de sobrecarga frente a la lista de argumentos vacía. Se llama al constructor seleccionado (que es uno de los constructores por defecto) para proporcionar el valor inicial para el nuevo objeto; - si
T
es un tipo de array, cada elemento del array se inicializa por defecto; - de lo contrario, no se hace nada: los objetos con duración de almacenamiento automática (y sus subobjetos) se inicializan a valores indeterminados.
Solo los tipos de clase (posiblemente calificados-cv) no simples (o sus conjuntos) con duración de almacenamiento automática se consideraron para ser inicializados por defecto cuando no se utiliza ningún inicializador. Los escalares y los tipos de datos simples con duración de almacenamiento dinámica se consideraron no inicializados (desde C++11, esta situación se reclasificó como una forma de inicialización predeterminada). |
(hasta C++11) |
Antes de C++03 (que introdujo inicialización de un valor), la expresión new T() así como un inicializador de miembro que nombra una base o un miembro con el inicializador en la forma de un par de paréntesis vacío se clasificó como inicialización por defecto, pero se especificó inicialización cero para los tipos que no son de clase. |
(hasta C++03) |
Si |
(hasta C++11) |
El uso de un valor indeterminado obtenido al inicializar por defecto una variable que no sea de clase de cualquier tipo es comportamiento indefinido (en particular, puede ser un representación trampa), excepto en los siguientes casos:
int f(bool b) { int x; // de acuerdo: el valor de x es indeterminado int y = x; // comportamiento indefinido unsigned char c; // de acuerdo: el valor de c es indeterminado unsigned char d = c; // de acuerdo: el valor de d es indeterminado int e = d; // comportamiento indefinido return b ? d : 0; // comportamiento indefinido si b es verdadera } |
(desde C++14) |
[editar] Notas
La inicialización por defecto de las variables que no son clases con duración de almacenamiento automática y dinámica produce objetos con valores indeterminados (objetos estáticos y locales al hilo son inicializados mediante la inicialización cero)).
Si T
es un tipo calificado con const
, debe de ser un tipo de clase con un constructor suministrado por el usuario.
Una referencia no puede ser inicializada mediante la inicialización por defecto.
[editar] Ejemplo
#include <string> struct T1 { int mem; }; struct T2 { int mem; T2() {} // "mem" no se encuentra en la lista de inicializadores }; int n; // estática, no clase, se hace una inicialización de dos fases: // 1) inicialización cero inicializa n a cero // 2) inicialización por defecto no hace nada, deja a n en cero int main() { int n; // no clase, valor indeterminado std::string s; // clase, llama al ctor por defecto, valor es "" (cadena vacía) std::string a[2]; // array, inicialización por defecto de los elementos, valor es {"", ""} // int& r; // ERROR: una referencia // const int n; // ERROR: no clase, constante // const T1 nd; // ERROR: clase constante con ctor por defecto implícito T1 t1; // clase, llama ctor por defecto implícito const T2 t2; // clase constante, llama al ctor por defecto suministrado por el usuario // t2.mem is inicializada por defecto (a un valor indeterminado) }