7
votes

Include incluse en C ++ .. Comment ça marche?

Dupliqué possible:
Un moyen approprié de #include quand il y a une dépendance circulaire?

Je suis assez nouveau à C ++ et j'ai demandé la question posée dans le titre. Ou plus précisément: si a.h inclut b.h et b.h inclut A.H, je reçois un message d'erreur car "inclure # fichier" C: ... \ a.h "s'incline". Fichier: B.H

Je n'ai pas pu trouver un moyen de contourner cela, et ma configuration générale nécessite à peu près la relation entre ces classes. Toute possibilité de faire ce travail?


1 commentaires

Bonne question. PRÉPROCESSIONS DE TRAVAILLE DE TRAVAILLAGE PAR LIGNE, vous étudieriez comment #Ifdef , #define et #endif travail :-)


7 Réponses :


6
votes

simple: ne laissez pas A.h inclure b.H. Et vice-versa.

En général, les fichiers d'en-tête doivent inclure le moins possible. Vous pouvez utiliser la déclaration à terme pour contourner beaucoup d'inclinaison. La seule fois que vous devez absolument inclure quelque chose dans un en-tête, s'il existe des objets utilisés comme non-références dans cet en-tête.

Évitez donc de le faire. Utilisez PIMPL pour éviter de mettre des membres de la classe dans des en-têtes. Et à moins que ce soit un code de modèle ou si vous avez besoin du support d'inlinage, n'écrivez pas le code réel dans les en-têtes.

Le pire des cas est que vous devez créer un C.H qui définit ce que a.h et b.h besoin.


1 commentaires

Merci hnicol, c'est un bon point. En général (pas dans ce cas particulier de double inclusion), pouvez-vous expliquer pourquoi préféreriez-vous une déclaration en avant à une inclusion normale?



0
votes

Vous avez un Dépendance circulaire . Il peut être résolu en utilisant Inclure les gardes .


0 commentaires

7
votes

Utilisez Inclure des gardes dans vos fichiers d'en-tête. http://fr.wikipedia.org/wiki/include_guard xxx

De cette façon si vos fichiers d'en-tête sont inclus plus d'une fois que le compilateur les ignore.

aussi en règle générale si vous y compris BH qui a AH, il serait préférable d'inclure AH et BH dans votre application au lieu de s'appuyer sur l'inclusion de BH

Ne mettez également que des déclarations dans le fichier d'en-tête.

Évitez les définitions à tous les coûts des fichiers d'en-tête.


0 commentaires

0
votes

Essayez d'ajouter des gardes d'en-tête,

#ifndef _A_H_
#define _A_H_
...
..
.
#endif /* #ifndef _A_H_ */


0 commentaires

0
votes

Lorsqu'un fichier d'en-tête est ajouté à un fichier, il est inclus lors de la partie prétraite de la compilation. Donc, y compris b.h dans a.h. Et y compris a.h à B.H. C'est une sorte d'infiniment récursive et le fichier est inclus plusieurs fois.

y compris B.H dans a.h monte à a.h <- B.H Y compris a.h in b.h équivaut à bh <- a.h

Son roi de boucle récursive infinie.


0 commentaires

1
votes

Vous n'avez pas dit ce que sont ces dépendances mutuelles, donc celles-ci ne sont que des suppositions. Dans tous ceux-ci, je suppose que A.h définit classe A et b.h défini classe B .

cas 1 : la dépendance mutuelle est via des pointeurs ou des références.
Par exemple, classe A contient un élément de données de type B * et inversement. Dans ce cas, aucun en-tête n'a besoin de #include l'autre. Utilisez une déclaration à terme à la place.

cas 2 : la dépendance mutuelle passe par des objets.
Par exemple, Classe A contient un élément de données de type B et inversement. Dans ce cas, vous êtes hosté.

cas 3 : dépendances mixtes.
Par exemple, classe A contient un membre de données de type B mais class b contient un élément de données de type a * . Maintenant, a.h a besoin de #include b.h , mais b.h a simplement besoin d'une déclaration d'avance de classe A .

Vous devez toujours utiliser une sorte de garde d'une seule fois inclure pour empêcher une en-tête d'être incluse plusieurs fois.


0 commentaires

1
votes

En supposant que dans chaque en-tête, vous avez une classe, vous pouvez faire comme ceci:

Fichier d'en-tête: "AH" STRY> P>

Class B {
public:
  A name_of_A_;
}

#endif


2 commentaires

La présente présente à la fin de chaque fichier d'en-tête est totalement inutile. Déclaration avant comme classe A; est un mécanisme pour dire au compilateur qu'une classe A sera présente plus tard, identique pour la classe B. À ce stade, peu importe que l'une des catégories A ou B sera résolue, car vous venez de dire au compilateur qu'ils Tous deux seront là à la fin de la compilation en utilisant la déclaration à terme. Ainsi, la comporte à la fin du fichier d'en-tête peut être supprimée car elles ne servent aucun but. Salutations ;)


À droite! Merci de le pointer.