with initialize argument c++ c++11 initialization

argument - c++ initialize class with parameters



Necesita alguna aclaración con 8.5.p7 en el estándar C++ 11 (3)

El párrafo 8.5p7 de la Norma C ++ 11 establece:

Valorizar-inicializar un objeto de tipo T significa:

  • si T es un tipo de clase (posiblemente cv calificado) (Cláusula 9) con un constructor proporcionado 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 sindicalizada (posiblemente cv calificado) sin un constructor proporcionado por el usuario, entonces el objeto se inicializa en cero y, si el constructor predeterminado implícitamente declarado de T no es trivial, se llama a ese constructor.

  • si T es un tipo de matriz, entonces cada elemento se inicializa en valor;

  • de lo contrario, el objeto tiene cero inicialización.

Tengo un problema para entender los caracteres en negrita de arriba. ¿Cómo la llamada adicional del constructor predeterminado implícito de T podría alterar la inicialización de cero, que acaba de ocurrir en este caso?


Aquí hay un ejemplo concreto:

class A { int a; public: A() : a(1) {} }; class B { int b; A c; };

B cae en esta categoría: es un tipo de clase no sindical sin un constructor proporcionado por el usuario. Por lo tanto, si una B se inicializa en valor, primero se inicializará en cero (así que tanto b como ca se establecerán en 0), y luego se llamará al constructor predeterminado (que llamará al constructor de A y establecerá ca en 1) )

Con la regla de as-if , el optimizador puede combinarlas en un solo paso (lo que establecerá b a 0 y ca a 1), ya que nadie puede ver el objeto entre la inicialización cero y el constructor predeterminado.


T puede no tener su propio constructor predeterminado explícito, pero puede derivarse de U que lo haga, y / o tener un miembro de clase tipo V que sí lo haga.


struct S { int a, b; S() : b(10) {} }; struct T { S s; }; int main() { S s{}; T t{}; }

t es el valor inicializado y T no tiene un constructor proporcionado por el usuario. Sin embargo, el constructor predeterminado implícitamente de T no es trivial.

s también se inicializa el valor, pero S tiene un constructor proporcionado por el usuario.

sa tendrá un valor indeterminado. pero tsa es cero debido a la inicialización cero que precede a la llamada del constructor predeterminado. Tanto sb como tsb se establecen en el valor 10.