2009-06-15 6 views
14

Je suis nouveau en C++, donc cette question peut être basique:Deux classes qui se réfèrent

J'ai deux classes qui ont besoin de se référer les unes aux autres. Chacun est dans son propre fichier d'en-tête, et # include est le fichier d'en-tête de l'autre. Lorsque j'essaie de compiler, j'obtiens l'erreur "ISO C++ interdit la déclaration de 'Foo' sans type" pour l'une des classes. Si je change les choses pour que l'en-tête opposé soit analysé en premier, j'obtiens la même erreur avec l'autre classe.

Est-il possible en C++ d'avoir deux classes qui ont besoin de références les unes aux autres?

Pour plus de détails: J'ai une classe "App" et une classe "Window". App doit se référer à la fenêtre pour faire la fenêtre. La fenêtre a un bouton qui rappelle App, il a donc besoin d'une référence à App. Si je ne peux pas faire se référer deux classes, y a-t-il une meilleure façon de le mettre en œuvre?

+2

Il convient de noter que les dépendances mutuelles doivent être évitées autant que possible. Serait-il sensé de factoriser la fonctionnalité que les appels de boutons dans l'application dans un objet contrôleur-ISH distinct? –

+0

Je trouve ce problème assez souvent dans mes petits jeux. J'ai un objet World contenant des objets Game qui doivent faire référence à l'objet World, par exemple. Détection de collision. Je n'ai pas trouvé un bon moyen de refactoriser ça. (Et btw, se réveiller une discussion de 7 ans quelque chose pour gagner une sorte de badge) – Johan

Répondre

27

Vous pouvez utiliser des déclarations directes dans les fichiers d'en-tête pour contourner les dépendances circulaires tant que vous n'avez pas de dépendances d'implémentation dans les en-têtes. Dans Window.h, ajoutez cette ligne:

class App; 

En App.h, ajoutez cette ligne:

class Window; 

Ajoutez ces lignes avant que les définitions de classe. Ensuite, dans les fichiers source, vous pouvez inclure les en-têtes pour les définitions de classes réelles. Si vos définitions de classe font référence à des membres de l'autre classe (par exemple, dans inlines), elles doivent être déplacées dans le fichier source (ne sont plus en ligne).

8

La déclaration vers l'avant est la voie à suivre.

Si vous utilisez pointers \ reference dans l'en-tête de la classe, la déclaration Forward des deux côtés fonctionnerait pour vous.

Si vous créez l'objet en tant que membre de classe, vous devez inclure l'en-tête lui-même. (La déclaration forward ne fonctionnera pas car le compilateur a besoin d'une définition de classe pour connaître la taille).

Refer C++ FAQ for solving such senario:

Si vous créez la fenêtre en tant que membre comprennent alors l'en-tête de la fenêtre dans l'App mais à la même fenêtre de temps ne devrait pas inclure l'en-tête de l'App. Utilisez la combinaison de pointeur vers App et la déclaration directe ici.

Questions connexes