2010-08-07 6 views
1

déclarant un tableau de struct:un compilateur généré constructeur par défaut en C++

struct Tables { 
     int i; 
     int vi[10]; 
     Table t1; 
     Table vt[10]; 
}; 

Tables tt; 

en supposant qu'un contructor Deault par l'utilisateur est défini pour le tableau.

ici tt.t1 sera initialisé en utilisant le constructeur par défaut pour Table, ainsi que chaque élément dans tt.vt. D'autre part, tt.i et tt.vi ne sont pas initialisés car ces objets ne sont pas de type classe. Par contre, tt.i et tt.vi ne sont pas initialisés. Donc nous restons avec un objet semi-initialisé tt.

si j'ai bien compris - si tt.i ou tt.vi ne seront pas initialisés explicitement dans le code, après la création de tt, une erreur sera générée si nous essayons d'en lire une valeur?

2) Quelqu'un peut-il m'expliquer, pourquoi les concepteurs de cpp ne voulaient pas simplement initialiser les types int intégrés et int [] à zéro?

+0

Je suppose que le constructeur par défaut (même s'il s'exécute) ne fait rien. –

+1

Tout est une question de coût. Les développeurs C++ ne veulent pas payer le coût de l'initialisation s'ils n'en ont pas. Voir: http://stackoverflow.com/questions/1910832/c-why-arent-pointers-initialized-with-null-by-default/1910992#1910992 –

Répondre

4

Non, aucune erreur ne sera générée. Vous aurez un léger cas de comportement indéfini. Cependant, comme les entiers n'ont pas de valeurs d'interruption, il est impossible de détecter le comportement. Notez que le langage C++ lui-même ne génère que très, très rarement des exceptions - sur les seules fois où je peux penser à l'endroit où il effectue une distribution invalide à une référence via dynamic_cast, et quand new ne parvient pas à allouer. Bien sûr, la bibliothèque standard peut lancer un certain nombre de conditions d'erreur. Pour ce qui est de savoir pourquoi C++ fonctionne ainsi (et C aussi), une bonne initialisation prend du temps, et si cela n'est pas nécessaire c'est du temps perdu. Par exemple, si vous deviez lire immédiatement l'entrée de l'utilisateur dans ces variables, il est inutile de les initialiser avant de le faire.

+0

mais je pensais que 'dynamic_cast' ne lançait aucune erreur? Je crois que si les types ne sont pas compatibles alors le pointeur retourné sera simplement "null". – phunehehe

+1

@phunehehe Il lance lors de la conversion en * référence *. –

+0

merci Nell, je ne le savais pas. hmm mais je suppose que je voudrais juste utiliser le cast du pointeur. – phunehehe

3

Une erreur ne sera pas levée, ce n'est pas Java. :)

Ce qui sera retourné sera ce qui se passera dans la mémoire à ce moment-là. Ce que vous avez est une variable "non initialisée". Il pourrait être 0. Il pourrait être 42. Ce sera quelque chose d'imprévisible à chaque fois.

Morale de l'histoire - initialisez TOUTES vos variables. Ne pas le faire peut causer des bogues incroyablement difficiles sur la route.

Puisque c'est C++, utilisez un constructeur par défaut pour initialiser votre struct:

 
struct Tables { 
     int i; 
     int vi[10]; 
     Table t1; 
     Table vt[10]; 

Tables() { 
    i = 0; 
    for (int iter = 0; iter < 10; iter++) 
    vi[iter] = 0; 
} 

}; 

Tables tt; 
+0

Strictement parlant, cela ne les initialise pas - il leur assigne. Que ce soit ou non une bonne idée dépend de ce que l'utilisateur va faire avec eux. –

1

Puisqu'ils sont pas pointer types, ils seront remplis avec tout ce qui est sur la pile à cet endroit. S'il s'agissait de types de pointeurs et que vous les déréférenciez sans les initialiser correctement, alors oui vous auriez des problèmes.

Questions connexes