2011-08-16 12 views
8

Siempre pensé que la creación de un nuevo objeto siempre llamaría al constructor predeterminado de un objeto, y que el constructor fuera explícito o el compilador lo generara automáticamente no importaba. De acuerdo con this highly regarded answer a una pregunta diferente, esto cambió de una manera sutil entre C++ y C++ 98 03 y ahora funciona de esta manera:Diferencia entre default-initialize e value-initialize en C++ 03?

struct B { ~B(); int m; }; // non-POD, compiler generated default ctor 
new B; // default-initializes (leaves B::m uninitialized) 
new B(); // value-initializes B which zero-initializes all fields since its default ctor is compiler generated as opposed to user-defined. 

¿Puede alguien decirme:

  1. ¿Por qué el estándar cambió, es decir, qué ventaja da esto o qué es posible ahora que no era antes;
  2. ¿Qué representan exactamente los términos "default-initialize" y "value-initialize"?
  3. ¿Cuál es la parte relevante de la norma?
+0

La parte relevante del nuevo estándar C++ 11 es 8.5 ("Iniciales") cláusulas 5,6,7. –

+0

Tal vez le da a las personas la opción de usar el controlador predeterminado o no. En la versión anterior de C++, los corchetes normalmente se perdían cuando no había parámetros. Entonces, tener los corchetes en la nueva opción afectará menos código heredado. – QuentinUK

+0

No lo llamaría cambio, sino corrección. Al menos tiene sentido en el contexto de, p. std :: map donde los valores creados por [] tienen valor inicializado, por lo que, por ejemplo, std :: map todos U * están iniciados en 0 – PlasmaHH

Respuesta

2

No sé cuáles son las razones de todo el cambio (o cómo el estándar era antes), pero en la forma en que es, básicamente default-inicialización es o bien llamar a un constructor definido por el usuario o no hacer nada (un montón de agitar manualmente aquí: esto se aplica recursivamente a cada subobjeto, lo que significa que los subobjetos con un constructor predeterminado se inicializarán, los subobjetos sin constructores definidos por el usuario se dejarán sin inicializar).

Esto se incluye en el solo paga por lo que usted quiere filosofía del lenguaje y es compatible con C en todos los tipos que son compatibles con C. Por otro lado, puede solicitar inicialización de valor, y eso equivale a llamar al constructor predeterminado para los objetos que lo tienen o inicializando a convertido al tipo apropiado para el resto de los subobjetos.

Esto se describe en §8.5 Inicializadores, y no es trivial para navegar. Las definiciones para cero inicializan, default-inicializar y valor-INICIALIZACIÓN son el párrafo quinto:

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 sindical, cada elemento de datos no estático y cada subobjeto de clase base se inicializan como cero;

- si T es un tipo de unión, el primer miembro de datos con nombre del objeto89) 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 default-inicializar un objeto de tipo T significa:

- si T es a-POD no tipo de clase (cláusula 9), el constructor predeterminado de T se llama (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 se inicializa en cero.

Para valor-inicializar un objeto de tipo T significa:

- 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 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, cada elemento se inicializa en valor;

- de lo contrario, el objeto es inicializada a cero

un programa que llama para default-inicialización o valor de inicialización de una entidad de tipo de referencia es Formato incorrecto. Si T es un tipo calificado para cv, la versión cv no calificada de T se usa para estas definiciones de inicialización cero, inicialización predeterminada e inicialización de valor.

+0

Su párrafo inicial ha definido el comportamiento de Inicialización predeterminada como ya sea usando el ctor o su izquierda sin inicializar. Mi pregunta es la interpretación de la cita incluida de la sección Initializer 8.5 que define la inicialización predeterminada que tiene como paso final ... "; de lo contrario, el objeto se inicializa en cero". Parece sugerir que si no hay ctor, entonces use las reglas de inicialización cero vs sin dejarla sin inicializar. – TheChrisONeil

+0

@CBO: Esa cita en particular es de C++ 03, en C++ 11 el último elemento ha cambiado y dice: * de lo contrario, no se realiza ninguna inicialización *. La clave en este punto es lo que se escribe unos párrafos más adelante. Para un objeto sin inicializador proporcionado, en C++ 03 el objeto se deja sin inicializar (en/9), en C++ 11 el objeto es * inicializado por defecto * (/ 12).No estoy seguro si esto responde a su preocupación –

+0

Tiene sentido y gracias por dar seguimiento. Recomendaría actualizar su publicación para incluir ahora el contenido de C++ 11. – TheChrisONeil

Cuestiones relacionadas