Dépendance cyclique

Dépendance cyclique

par Florian Xavier Käslin,
Number of replies: 5

Bonjour,

Je suis en train d'essayer d'implémenter tout ce qu'il faut pour "Dessiner" les objets du projets.

J'ai donc une classe "Dessinable", une classe "Toupie", une classe "Systeme" qui contient des toupies (ces deux classes sont elles mêmes des dessinables), ainsi qu'une classe "SupportADessin".  J'ai fait les fonctions et méthodes dont je pense avoir besoins, fait les includes nécessaires dans chaque .h et .cc, et j'ai compiler. 

Je me retrouve systématiquement avec ce type d'erreurs lors de la compilation:


Après quelques recherches, je pense que le problème vient de deux boucles de dépendances cycliques au niveau des includes:

1) entre Dessin.h, SupportADessin.h et Systeme.h

2) entre Toupie.h, Dessin.h et SupportADessin.h

J'ai essayé de résoudre le problème, mais malgré mes recherches, je ne trouve pas de solutions pour toutes que les erreurs soient résolues.

Afin de clarifier un peu la situation, voici un petit schéma de mon programme. Les classes y sont indiquées par leur nom, les fichiers par des rectangles contenant les noms des classes et annotés avec le nom du fichier, les liens d'héritage avec des flèche grises entres les classes, et les lien d'inclusion  avec des flèches bleues entre les fichiers.

[ SUPPRIMÉ ]


Merci beaucoup d'avance et bonne soirée.

Florian Käslin.

(Modifié par Jean-Cédric Chappelier : veuillez ne pas expliquer votre projet à toute la classe !!)

In reply to Florian Xavier Käslin

Re: Dépendance cyclique

par Josué Antoine Maechling,

C'est un problème récurrent que beaucoup d'autres auront aussi. Il faut souvent procéder à tâtons et tester à chaque retrait/ajout d'include.

Ma technique en général (évidemment il y a un cas spécial avec Dessinable-SupportADessin mais ça c'est donné dans l'introduction au graphisme) :

Dans un .h :

-On ne met PAS d'include d'autres .h (sauf la super classe comme Dessinable, et SupportADessin bien sûr, tout ça pour des objets dessinables évidemment)

Dans un .cc :

-On peut mettre tous les include de .h nécessaires (dont Dessinable et SupportADessin aussi)

Ne pas oublier, à chaque include de .h, de l'ajouter aussi dans le .o dans le Makefile.

Je précise pour tout le monde que "par chance" d'autres manières de procéder peuvent fonctionner, mais soyez avertis que vous pouvez vous retrouver un jour à être bloqués et à devoir tout refaire comme indiqué. C'est la manière la plus générale et efficace que j'ai trouvée.

Dans le cas particulier de SupportADessin, attention à ne mettre AUCUN include ! Il faut juste faire des prédéclarations des classes nécessaires ! (genre class Systeme; avant de commencer à écrire la classe SupportADessin)

J'espère que ma réponse pourra aider.


In reply to Josué Antoine Maechling

Re: Dépendance cyclique

par Deleted user,

Juste une petite remarque (je ne sais pas si j'ai bien compris ta réponse).

La pré-déclaration est effectivement utile. Cependant, bien qu'avec pré-déclaration d'une classe A on puisse définir des pointeurs A* dans une autre classe B, la classe B ne pourra pas directement contenir d'objets type A.

class A;
class B{
A* var_; //OK
A var2_; //Erreur!
};

C'est entre autre dû au fait que pour que le compilateur sache combien de mémoire allouer à un objet B, il faut savoir combien de mémoire donner à l'objet A! Et pour cela, simplement spécifier l'existence de A ne suffit pas. On ne peut donc pas systématiquement se passer d'include entre headers.

In reply to Deleted user

Re: Dépendance cyclique

par Josué Antoine Maechling,

Absolument on ne peut pas se passer des headers en général, mais dans notre SupportADessin c'est un cas tout à fait particulier, et il n'y a absolument aucun attribut (dans la super classe). Et c'est la méthode à suivre (je vous laisse vous inspirer du code de l'introduction au graphisme pour ça).

In reply to Josué Antoine Maechling

Re: Dépendance cyclique

par Jean-Cédric Chappelier,

Comme nous avons eu quelques questions à ce sujet aujourd'hui :
j'insiste pour clarifier : c'est en effet le cas dans CE CAS PARTICULIER ; mais en général la règle reste : pour chaque fichier (.cc ou .h) pris indépendamment du reste (c.-à-d. donc pour lui-même en tant que tel), il faut mettre tous les includes dont ce fichier a besoin et uniquement ceux dont ce fichier a besoin.