"Se um trabalhador quiser fazer bem o seu trabalho, ele deve primeiro afiar suas ferramentas." - Confúcio, "Os Analectos de Confúcio. Lu Linggong"
Primeira página > Programação > Como lidar com dependências circulares entre cabeçalhos em C++?

Como lidar com dependências circulares entre cabeçalhos em C++?

Publicado em 2024-11-12
Navegar:908

 How to Handle Circular Dependencies Between Headers in C  ?

Cabeçalhos incluindo-se mutuamente em C

Em C , ocasionalmente é necessário que os cabeçalhos se incluam. No entanto, isso pode levar a problemas, especialmente quando se trata de onde colocar as instruções #include.

Macros internos ou externos

Em geral, as instruções #include devem ser colocado dentro de macros, como #ifndef include guards. Isso evita a recursão infinita durante a compilação, conforme demonstrado no exemplo a seguir:

// 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_

Colocar as instruções #include fora das macros resulta na recorrência do compilador indefinidamente devido à inclusão mútua entre A.h e B.h.

Tipos não declarados

No entanto, colocar as instruções #include dentro das macros pode levar a problemas com tipos não declarados. Por exemplo, considere o seguinte código:

// 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_

Nesse caso, o compilador reclamará que A é um tipo não declarado dentro de B.h. Isso ocorre porque a declaração futura em A.h não é visível quando B.h está incluído.

Solução: declarações futuras

Para resolver esses problemas, é melhor usar declarações futuras e inclua o cabeçalho contendo a definição completa quando necessário. Neste exemplo, uma declaração futura de A deve ser adicionada a B.h antes da definição 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_
Tutorial mais recente Mais>

Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.

Copyright© 2022 湘ICP备2022001581号-3