213 votes

Que signifient les expressions suivantes en C ++: initialisation zéro, par défaut et valeur?

Que signifient les phrases suivantes en C ++:

  • initialisation zéro,

  • initialisation par défaut et

  • initialisation de valeur?

Que devrait savoir un développeur C ++ à leur sujet?

91voto

Kirill V. Lyadvinsky Points 47627

C++03 Standard 8.5/5:

À zéro-initialiser un objet de type T signifie:
- si T est un type scalaire (3.9), l'objet est défini à la valeur de 0 (zéro) est converti en T;
- si T est une non-union type de classe, chaque non membre de données et chaque classe de base sous-objet est initialisé à zéro;
- si T est un type d'union, l'objet premier de données nommée membre est initialisé à zéro;
- si T est de type tableau, chaque élément est initialisé à zéro;
- si T est un type de référence, pas d'initialisation est effectuée.

À défaut d'initialisation d'un objet de type T signifie:
- si T est un non-POD type de classe (article 9), le constructeur par défaut pour T est appelé (et l'initialisation est mal formé, si T n'a pas de accessible le constructeur par défaut);
- si T est de type tableau, chaque élément par défaut est initialisée;
- sinon, l'objet est initialisé à zéro.

À la valeur d'initialiser un objet de type T signifie:
- si T est un type de classe (clause 9) avec un utilisateur déclaré par le constructeur (12.1), puis le constructeur par défaut pour T est appelé (et l'initialisation est mal formé, si T n'a pas de accessible le constructeur par défaut);
- si T est une non-union type de classe sans un utilisateur déclaré par le constructeur, puis tous les non-membre de données statiques et de la classe de base de la composante de T est la valeur initialisée;
- si T est de type tableau, chaque élément est la valeur initialisée;
- sinon, l'objet est initialisé à zéro

Un programme qui appelle à défaut d'initialisation ou de la valeur d'initialisation d'une entité de type de référence est mal formé. Si T est un cv qualifiés de type, le cv-non qualifiés de la version de T est utilisé pour ces définitions de zéro-initialisation par défaut de l'initialisation et de la valeur d'initialisation.

67voto

Michael Burr Points 181287

Une chose à comprendre, c'est que la "valeur d'initialisation' est de nouveau avec le C++ 2003 standard - il n'existe pas dans l'original de 1998 standard (je pense que ça pourrait être la seule différence, c'est plus de précisions). Voir Kirill V. Lyadvinsky de réponse pour les définitions directement à partir de la norme.

Voir cette réponse précédente sur le comportement de l' operator new pour plus de détails sur le comportement différent de ces type d'initialisation et quand ils coup de pied dans (et quand elles diffèrent de c++98 C++03):

Le point principal de la réponse est:

Parfois, la mémoire renvoyée par le nouvel opérateur sera initialisé, et parfois, il ne sera pas selon que le type que vous êtes newing est une GOUSSE, ou si c'est une classe qui contient POD membres et est à l'aide d'un générées par le compilateur par défaut du constructeur.

  • En C++1998 il y a 2 types d'initialisation: zéro et par défaut
  • En C++2003 une 3ème type d'initialisation, la valeur d'initialisation a été ajouté.

À dire qu'ils ont moins, c'est plutôt complexe et lorsque les différentes méthodes de coup de pied dans sont subtiles.

Une chose à savoir, c'est que MSVC suit le C++98 règles, même dans VS 2008 (VC 9 ou cl.exe la version 15.x).

L'extrait suivant montre que MSVC et de Numérique, Mars suivre C++98 règles, tandis que GCC 3.4.5 et Comeau, suivez la C++03 règles:

#include <stdio.h>
#include <string.h>
#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)];
    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
    printf( "m  is %d\n", pB->m);
    return 0;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X