197 votes

Le constructeur par défaut initialiser types intégrés

Le constructeur par défaut (créé par le compilateur) initialiser intégré-types?

202voto

AndreyT Points 139512

Implicitement défini (par le compilateur) dans le constructeur par défaut d'une classe n'a pas d'initialiser les membres de types intégrés.

Toutefois, vous devez garder à l'esprit que, dans certains cas, l'initialisation d'une instance de la classe peut être effectuée par d'autres moyens. Pas par le constructeur par défaut, et non pas par le constructeur.

Par exemple, il est incorrect de croire que, par classe d' C la syntaxe C() toujours appelle le constructeur par défaut. Mais en réalité, la syntaxe C() effectue donc appelé valeur d'initialisation de l'instance de classe. Il sera uniquement appeler le constructeur par défaut si c'est l'utilisateur déclaré. (C'est en C++03. En en C++98 - seulement si la classe est non-POD). Si la classe n'a pas l'utilisateur déclaré constructeur, puis l' C() ne vais pas appeler le compilateur par défaut fourni par le constructeur, mais plutôt de réaliser un type spécial de l'initialisation, qui n'implique pas le constructeur de l' C . Au lieu de cela, il va directement la valeur d'initialisation de chaque membre de la classe. Pour les types intégrés-il à zéro de l'initialisation.

Par exemple, si votre classe n'a pas l'utilisateur déclaré constructeur

class C { 
  int x;
};

ensuite, le compilateur va implicitement en fournir un. Le compilateur fourni par le constructeur ne fait rien, ce qui signifie qu'il ne sera pas initialiser C::x

C c; // Compiler-provided default constructor is used
// Here `c.x` contains garbage

Néanmoins, la suite de l'initialisation sera zéro-initialiser x parce qu'ils utilisent l'explicite () initialiseur

C c = C(); // Does not use default constructor for `C()` part
           // Uses value-initialization feature instead
assert(c.x == 0);

C *pc = new C(); // Does not use default constructor for `C()` part
                 // Uses value-initialization feature instead
assert(pc->x == 0);

Le comportement de l' () initialiseur est à certains égards différents entre C++98 et C++03, mais pas dans ce cas. Pour la classe ci-dessus C il sera le même: () initialiseur effectue zéro de l'initialisation de l' C::x.

Un autre exemple de l'initialisation est effectuée sans la participation du constructeur est, bien sûr, agrégée d'initialisation

C c = {}; // Does not use any `C` constructors at all
assert(c.x == 0);

23voto

Steve Jessop Points 166970

Je ne suis pas tout à fait certain de ce que tu veux dire, mais:

struct A { int x; };

int a; // a is initialized to 0
A b;   // b.x is initialized to 0

int main() {
    int c;         // c is not initialized
    int d = int(); // d is initialized to 0

    A e;           // e.x is not initialized
    A f = A();     // f.x is initialized to 0
}

Dans chaque cas où je dis "non initialisé" - vous pouvez trouver que votre compilateur lui donne une cohérence de la valeur, mais la norme ne l'exige pas.

Beaucoup de la main-agitant obtient jeté autour, y compris par moi, comment construit-dans les types de "en effet" avoir un constructeur par défaut. En fait d'initialisation par défaut et la valeur d'initialisation sont définis dans la norme, qui, personnellement, j'ai regarder tous les temps. Seules les classes sont définies dans la norme d'avoir un implicite constructeur par défaut.

20voto

Joe Gauterin Points 9526

À toutes fins pratiques.


Cependant pour les implémentations sont techniquement compatible avec la norme C++, la réponse est que cela dépend si l'objet est POD ou pas, et comment l'initialiser. Selon la norme C++:

MyNonPodClass instance1;//built in members will not be initialized
MyPodClass instance2;//built in members will be not be initialized
MyPodClass* instance3 = new MyPodClass;//built in members will not be initialized
MyPodClass* instance3 = new MyPodClass() ;//built in members will be zero initialized

Cependant, dans le monde réel, ce n'est pas bien pris en charge et ne l'utilisez pas.


Les parties pertinentes de la norme sont l'article 8.5.5 et 8.5.7

3voto

mukeshkumar Points 1112

Conformément à la norme, il n'a pas, sauf si vous explicitement initialiser dans la liste des initialiseurs

1voto

e8johan Points 2259

Comme les orateurs précédents l'ont déclaré - non, ils ne sont pas initialisés.

C'est en fait une source de vraiment étrange erreurs systèmes d'exploitation modernes ont tendance à se remplir nouvellement alloué la mémoire des régions avec des zéros. Si vous vous attendez à ce que, il peut travailler la première fois. Cependant, comme votre application continue de fonctionner, delete-ing "et" new-ing objets, vous aurez tôt ou tard arriver à une situation où vous vous attendez à des zéros, mais non nulle restes d'une précédente objet se trouve.

Alors, pourquoi est-ce alors, n'est-ce pas tout new-ed de données nouvellement alloué? Oui, mais pas toujours de l'OS. L'OS a tendance à travailler avec les plus grands morceaux de la mémoire (par exemple, 4 MO à un moment), donc toutes les minuscules d'un mot-ici-trois-octets-il-allocations et deallocations sont traitées dans uyserspace, et ne sont donc pas remis à zéro.

PS. J'ai écrit "tendance", c'est à dire que vous ne pouvez même pas compter sur le succès de la première fois...

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