"Si un ouvrier veut bien faire son travail, il doit d'abord affûter ses outils." - Confucius, "Les Entretiens de Confucius. Lu Linggong"
Page de garde > La programmation > Comment gérer les dépendances circulaires entre les en-têtes en C++ ?

Comment gérer les dépendances circulaires entre les en-têtes en C++ ?

Publié le 2024-11-12
Parcourir:897

 How to Handle Circular Dependencies Between Headers in C  ?

En-têtes s'incluant les uns les autres en C

En C , il est parfois nécessaire que les en-têtes s'incluent les uns les autres. Cependant, cela peut entraîner des problèmes, en particulier lorsqu'il s'agit de savoir où placer les instructions #include.

Macros internes ou externes

En général, les instructions #include doivent être placé dans des macros, telles que #ifndef include guards. Cela empêche une récursion infinie lors de la compilation, comme le montre l'exemple suivant :

// A.h
#ifndef A_H_
#define A_H_

#include "B.h"

class A {
    private:
        B b;
    public:
        A() : b(*this) {}
};

#endif // A_H_
// B.h
#ifndef B_H_
#define B_H_

#include "A.h"

class B {
    private:
        A& a;
    public:
        B(A& a) : a(a) {}
};

#endif // B_H_

Le placement des instructions #include en dehors des macros entraîne la récurrence du compilateur indéfiniment en raison de l'inclusion mutuelle entre A.h et B.h.

Types non déclarés

Cependant, placer les instructions #include à l'intérieur des macros peut entraîner des problèmes avec les types non déclarés. Par exemple, considérons le code suivant :

// A.h
#ifndef A_H_
#define A_H_

class A;  // Forward declaration

#include "B.h"

class A {
    private:
        B b;
    public:
        A() : b(*this) {}
};

#endif // A_H_
// B.h
#ifndef B_H_
#define B_H_

#include "A.h"

class B {
    private:
        A a;  // Directly include A
    public:
        B(A& a) : a(a) {}
};

#endif // B_H_

Dans ce cas, le compilateur se plaindra que A est un type non déclaré dans B.h. En effet, la déclaration forward dans A.h n'est pas visible lorsque B.h est inclus.

Solution : Déclarations forward

Pour résoudre ces problèmes, il est préférable d'utiliser des déclarations forward. et incluez l'en-tête contenant la définition complète si nécessaire. Dans cet exemple, une déclaration directe de A doit être ajoutée à B.h avant la définition de B :

// B.h
#ifndef B_H_
#define B_H_

class A;  // Forward declaration

#include "A.h"

class B {
    private:
        A a;  // Directly include A
    public:
        B(A& a) : a(a) {}
};

#endif // B_H_
Dernier tutoriel Plus>

Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.

Copyright© 2022 湘ICP备2022001581号-3