だから私はいくつかのクラスB関数を呼び出したいクラスAを持っています。だから私は「bh」を含めます。しかし、クラス B では、クラス A の関数を呼び出したいと考えています。「あ」を入れると無限ループになってしまいますよね?私はそれについて何ができますか?
4 に答える
メンバー関数の宣言のみをヘッダー (.h) ファイルに入れ、メンバー関数の定義を実装 (.cpp) ファイルに入れます。その場合、ヘッダー ファイルは相互にインクルードする必要はなく、どちらの実装ファイルにも両方のヘッダーをインクルードできます。
メンバー シグネチャでも他のクラスを参照する必要がある場合は、前方宣言を使用できます。
class A;
これにより、ポインターと参照型 (A*
およびA&
)を使用できますが、A
それ自体は使用できません。また、メンバーを呼び出すこともできません。
例:
// a.h
struct B; // forward declaration
struct A {
void foo(B* b); // pointers and references to forward-declared classes are ok
};
// b.h
struct A; // forward declaration
struct B {
void bar(A& a); // pointers and references to forward-declared classes are ok
};
// a.cpp
#include "a.h"
#include "b.h"
void A::foo(B* b) {
b->bar(*this); // full declaration of B visible, ok to call members now
}
// b.cpp
#include "a.h"
#include "b.h"
void B::bar(A& a) {
a.foo(this); // full declaration of A visible, ok to call members now
}
各クラス (A および B) には、ヘッダー ファイルと実装ファイルが必要です。
各ヘッダー ファイル (例: A.h
) には、他のヘッダー ファイル (例: B.h
) を含めるべきではありませんが、他のクラスへの前方参照 (例: のようなステートメントclass B;
) を含めることができ、その宣言で他のクラスへのポインターおよび/または参照を使用することができます (たとえば、データ メンバーおよび/またはメソッド パラメータとして をclass A
含む場合があります)。B*
各 CPP ファイル (例: A.cpp
) には、複数のヘッダー ファイル (例:A.h
およびB.h
) が含まれる場合があります。各 CPP ファイルには、最初に独自のヘッダー ファイルをインクルードすることをお勧めします (たとえば、インクルードしてからをA.cpp
インクルードし、インクルードしてからをインクルードする必要があります)。A.h
B.h
B.cpp
B.h
A.h
各ヘッダー ファイルには、クラスの定義ではなく、宣言のみを含める必要があります。たとえば、クラスのメソッドのシグネチャをリストしますが、メソッド本体/実装はリストしません (メソッド本体/実装は.cpp
ファイルにあり、ヘッダー ファイル内)。ヘッダー ファイルには実装の詳細が含まれていないため、他のクラスの詳細に依存しません (参照する必要はありません)。せいぜい、たとえばB
がクラスの名前であることを知る必要があるだけです。これは、ヘッダー ファイルを別のヘッダー ファイルにインクルードする代わりに、前方宣言から取得できます。
前方宣言を使用して問題を回避することもできます。
#ifndef
、#define
および#endif
.h ファイルを囲んでみてください。