C で相互にインクルードするヘッダー
C では、ヘッダーが相互にインクルードする必要がある場合があります。ただし、特に #include ステートメントを配置する場所に関して問題が発生する可能性があります。
マクロの内部または外部
一般に、#include ステートメントは次のようにする必要があります。 #ifndef include ガードなどのマクロ内に配置できます。これにより、次の例に示すように、コンパイル中の無限再帰が防止されます:
// 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 の間の相互包含により、コンパイラが無限に再帰的に実行されます。
Undeclared Types
]ただし、#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 内で宣言されていない型であると警告します。これは、B.h が含まれる場合、A.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