Заголовки, включающие друг друга, в C
В C иногда бывает необходимо, чтобы заголовки включали друг друга. Однако это может привести к проблемам, особенно когда речь идет о размещении операторов #include.
Внутри или снаружи макросов
В общем, операторы #include должны помещаться внутри макросов, например #ifndef include Guards. Это предотвращает бесконечную рекурсию во время компиляции, как показано в следующем примере:
// 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_
Размещение операторов #include вне макросов приводит к бесконечной рекурсии компилятора из-за взаимного включения между A.h и B.h.
Необъявленные типы
Однако размещение операторов #include внутри макросов может привести к проблемам с необъявленными типы. Например, рассмотрим следующий код:
// 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_
В этом случае компилятор сообщит, что A является необъявленным типом в B.h. Это связано с тем, что предварительное объявление в A.h не отображается, когда включен B.h.
Решение: предварительные объявления
Чтобы решить эти проблемы, лучше всего использовать предварительные объявления и при необходимости включите заголовок, содержащий полное определение. В этом примере предварительное объявление A должно быть добавлено к B.h перед определением 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_
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3