Include récursif

Bonjour à tous,

Après avoir fait un peu de c++ il y a 15ans à l'école, j'essaye de retrouver mes anciennes marques

Je suis en train de faire une librairie pour Arduino et je suis confronté au problème suivant:

Soit une classe A et une classe U de méthodes statiques utilitaires (conversion de chaines et autres outils)

Certaines méthodes de ma classe U manipulent la classe A mais aussi dans ses méthodes membres, la classe A a besoin parfois de faire appel à des méthodes utiles de la classe U

Comment se passent les include ?

Si j'essaie de mettre un include A dans U ET un include U dans A, la classe U n'est plus reconnue et ça ne compile pas. Si je mets l'include que dans l'une des deux classes, pareil

Quelle est la bonne pratique pour ce cas de figure ?
Je suis persuadé buter sur un cas trivial

Merci à vous pour votre aide
Chris

T'as besoin de définir un "prototype de classe" dans celle où t'utilises moins l'autre :

Fichier A :

class U;
class A
{
};

Fichier U :

#include "A.h"

class U
{
};

Merci pour ton retour

J'imagine que ca fonctionne dans les deux sens...

Je veux essayer en tous cas
Bonne soirée

oui, ce que j'ai oublié de te dire c'est que pour que ca fonctionne bien, tes fonctions tu dois les définir dans un fichier .cpp à part :

Fichier A.h :

#ifndef __A_H
#define __A_H
class U;

class A
{
public:
    U variableMembreU;
    void maFonctionQuiUtiliseU();
    void maFonctionA();
};

#endif

Fichier A.cpp :

#include "A.h"
#include "U.h"

void A::maFonctionQuiUtiliseU();
{
    variableMembreU.maFonctionU();
}

void A:: maFonctionA();
{
    // mon code A
}

Fichier U.h

#ifndef __U_H
#define __U_H

#include "A.h"

class U
{
public:
    A variableMembreA;
    void maFonctionQuiUtiliseA();
    void maFonctionU();
};
#endif

Fichier U.cpp

#include "U.h"
#include "A.h"

void U::maFonctionQuiUtiliseA()
{
    variableMembreA.maFonctionA();
}

void U::maFonctionU
{
    // mon code U
}

Voilà, c'est un peu plus complet comme ça. Il faut faire attention à l'ordre des #include, aux #ifdef/#ifndef et surtout à mettre le code qui appelle les fonctions membres de U dans un .cpp qui inclut vraiment le fichier "U.h", et vice-versa.

Ca marche bien sur dans les deux sens, à condition de faire de même (prototype de classe).

Je crois surtout que les bonnes pratiques voudraient que ce genre de cas ne se rencontrent pas.

Encore merci

Juste pour info, je suis en train de faire une librairie de programmation de déclenchements hebdomadaire à partir d'un rtc

J'ai donc les classes suivantes
Time
DateTime
Task (définit une programmation, c'est à dire une action pour une heure et un jour de la semaine)
Manager qui gère la liste chaînée des Task, décide de la prochaine Task à exécuter etc etc
Utils: quelques méthodes utiles...

Voili voilou

Au boulot nous avions un jeu en ce qui concerne le nommage du code, c'était "ni oui ni non ni manager", parce que en fait, des "manager" il y en a de plein de sortes différentes... si t'arrives à l'appeler autrement que "manager" ce sera beaucoup plus parlant pour la relecture... :wink:

Sinon c'est pas mal comme idée, bonne continuation ! :wink:

Edit : par contre, plus généralement tu peux t'en sortir, sauf cas très rares, sans faire ce que tu me demandes ici. En utilisant la notion "d'interface" (au sens Java) : des classes abstraites pures.

fdufnews:
Je crois surtout que les bonnes pratiques voudraient que ce genre de cas ne se rencontrent pas.

Oui, tu as raison

Dans ma classe Utils, j'ai des méthodes statiques qui font des choses (ne serait ce qu'un affichage formaté) à partir d'une instance de DateTime.
Ces méthodes auraient plus leur place directement dans la classe DateTime....

Je vais déplacer :slight_smile:

Zorro_X:
Au boulot nous avions un jeu en ce qui concerne le nommage du code, c'était "ni oui ni non ni manager", parce que en fait, des "manager" il y en a de plein de sortes différentes... si t'arrives à l'appeler autrement que "manager" ce sera beaucoup plus parlant pour la relecture... :wink:

Sinon c'est pas mal comme idée, bonne continuation ! :wink:

Edit : par contre, plus généralement tu peux t'en sortir, sauf cas très rares, sans faire ce que tu me demandes ici. En utilisant la notion "d'interface" (au sens Java) : des classes abstraites pures.

Elle ne s'appelle pas simplement manager mais SchManager, Sch préfixant toutes les classes de la librairie dont le nom est Schedule
Ainsi, dans mon explorateur de projet, toutes les classes sont regroupées par librairie et non pas completement éparpillées :slight_smile:

Je ne sais pas si c'est suffisant pour concourir à ton jeu :Þ

wAx:
Je ne sais pas si c'est suffisant pour concourir à ton jeu :Þ

Non, là t'as perdu ! :stuck_out_tongue:
C'est suffisant pour concourir mais t'as perdu : il ne faut pas du tout utiliser le mot "manager", comme dans le jeu "ni oui ni non"... :wink: