Éviter les dépendances circulaires des fichiers d'en-tête [dupliquer]

cette question a déjà une réponse ici:

avez-vous un bon conseil sur la façon d'éviter les dépendances circulaires des fichiers d'en-tête , s'il vous plaît?

Bien sûr, depuis le début, j'essaie de concevoir le projet aussi transparent que possible. Cependant, à mesure que de plus en plus de fonctionnalités et de classes sont ajoutées et que le projet devient moins transparent, des dépendances circulaires commencent à se produire.

y a-t-il des règles générales, vérifiées et opérationnelles? Merci.

48
demandé sur Bunkai.Satori 2011-01-27 16:08:42

8 réponses

si vous avez une dépendance circulaire, alors vous faites quelque chose de mal.

comme par exemple:

foo.h
-----
class foo {
public:
   bar b;
};

bar.h
-----
class bar {
public:
   foo f;
};

Est illégale, vous voulez probablement:

foo.h
-----
class bar; // forward declaration
class foo {
   ...
   bar *b;
   ...
};

bar.h
-----
class foo; // forward declaration
class bar {
   ...
   foo *f;
   ...
};

et c'est ok.

règles générales:

  1. assurez-vous que chaque en-tête peut être inclus sur son propre.
  2. si vous pouvez utiliser des déclarations forward, utilisez-les!
48
répondu Artyom 2011-01-27 13:13:35
  • utiliser les déclarations transmises lorsque cela est possible.
  • déplacer n'importe quel en-tête inclut hors d'un dossier d'en-tête et dans le dossier de cpp correspondant si elles sont seulement nécessaires par le dossier de cpp. La façon la plus facile de faire respecter ceci est de faire le #include "myclass.h" la première inclusion dans myclass.cpp .
  • L'Introduction d'interfaces au point d'interaction entre classes séparées peut aider à réduire les dépendances.
15
répondu jon-hanson 2011-01-27 13:41:19

Une approche générale consiste à factoriser les points communs dans un troisième fichier d'en-tête qui est référencée par l'original deux fichiers d'en-tête.

Voir aussi meilleures pratiques en matière de dépendance circulaire

"
6
répondu Ed Guiness 2017-05-23 10:31:35

certaines des meilleures pratiques que j'utilise pour éviter les dépendances circulaires sont,

  1. Stick to OAD principles. Ne pas inclure un fichier d'en-tête, à moins que la classe incluse soit en relation avec la classe courante. Utilisez plutôt la déclaration forward.
  2. classes d'abrégé de dessin servant d'interface pour deux classes. Faites l'interaction des classes à travers cette interface.
6
répondu Sulla 2011-01-27 14:00:19

selon vos capacités de préprocesseur:

#pragma once

ou

#ifndef MY_HEADER_H
#define MY_HEADER_H
your header file
#endif

si vous trouvez qu'il est très ennuyeux de concevoir des fichiers en-tête peut-être makeheaders de Hwaci (concepteurs de DVCS SQLite et fossiles) pourrait être d'intérêt pour vous.

4
répondu Benoit 2011-01-27 13:10:18

ce que vous visez est une approche à plusieurs niveaux . Vous pouvez définir des couches où les modules peuvent dépendre de modules de couches inférieures, mais l'inverse doit être fait avec observateurs . Maintenant, vous pouvez encore définir à quel point vos couches doivent être fines et si vous acceptez la dépendance circulaire à l'intérieur des couches, mais dans ce cas j'utiliserais ceci .

3
répondu stefaanv 2017-05-23 12:02:36

en général, les fichiers d'en-tête doivent déclarer forwardly plutôt que d'inclure d'autres en-têtes dans la mesure du possible.

assure également que vous vous en tenez à une classe par en-tête.

alors vous ne vous tromperez presque certainement pas.

le pire couplage provient généralement du code template gonflé. Parce que vous devez inclure la définition à l'intérieur de l'en-tête, il conduit souvent à toutes sortes headers devant être inclus, et puis la classe que utilise le modèle inclut l'en-tête de modèle, y compris une charge d'autres choses.

pour cette raison, je dirais généralement: soyez prudent avec les gabarits! Idéalement, un modèle ne devrait pas avoir à inclure quoi que ce soit dans son code de mise en œuvre.

3
répondu CashCow 2011-01-27 13:58:52

Altough Artyom meilleure réponse fournie ce tutoriel est également grand et fournit quelques extenstions http://www.cplusplus.com/forum/articles/10627/

2
répondu rank1 2013-04-17 10:53:03