インクルード ガードを使用しているにもかかわらず、循環 #include の問題は解決しません。これは、#include ディレクティブを処理するプリプロセッサが、根本的な問題を露呈するような方法で動作するためです。
プリプロセッサは、#include ステートメントを検出すると、それを指定されたファイルの内容で置き換えます。たとえば、Physics.h に GameObject.h が含まれている場合、プリプロセッサは Physics.h の #include "GameObject.h" 行を GameObject.h の内容に置き換えます。
ただし、GameObject.h もPhysics.h がインクルードされると、循環依存関係が作成されます。プリプロセッサは、GameObject.h 内の #include "Physics.h" 行を検出すると、それを Physics.h の内容で置き換えようとしますが、Physics.h には GameObject.h も含まれているため、無限ループが発生します。
これをさらに理解するには、次のコードを検討してください。
// Physics.h #ifndef PHYSICS_H #define PHYSICS_H #include "GameObject.h" // Guard is present #endif // GameObject.h #ifndef GAMEOBJECT_H #define GAMEOBJECT_H #include "Physics.h" // Guard is also present #endif
プリプロセッサがこのコードを処理すると、次の結果が得られます。以下:
// Physics.h (after preprocessing) #ifndef PHYSICS_H #define PHYSICS_H // (GameObject.h was copy-pasted here) // (GameObject.h was copy-pasted again) #endif // GameObject.h (after preprocessing) #ifndef GAMEOBJECT_H #define GAMEOBJECT_H // (Physics.h was copy-pasted here) // (Physics.h was copy-pasted again) #endif
ご覧のとおり、Physics.h と GameObject.h の両方に互いのコピーが含まれており、循環依存関係が生じています。
この問題を解決するには、次のようにします。循環 #include を避け、代わりに前方宣言を使用することが重要です。前方宣言は、その定義を含めずに型の存在を宣言するため、コンパイラーは型のすべての詳細を必要とせずに続行できます。
以上が#include の循環問題を防ぐためにインクルード ガードを使用しないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。