2 つのクラス タイプと、これらのタイプごとに 1 つのオブジェクトがあります。1 つのクラス タイプは Player で、Player.h に Player タイプの Charles というクラスを作成しました。もう 1 つのクラスは Karatoise 型の Karatoise1 で、Karatoise.h に Karatoise1 が作成されます。Karatoise1 と Charles の両方に格納されている整数の一部を確認できるようにする必要があります。両方とも内部のすべての変数が公開されており、Karatoise.cpp には Player.h が含まれ、Player.cpp には Karatoise.h が含まれています。どちらのヘッダー ファイルにもヘッダー ガードがあります。これは、ヘッダー ファイルの内部が #ifndef、#define、および #endif ステートメントで囲まれている状態で呼び出されると思います。ただし、このセットアップ ビジュアル スタジオを使用すると、Charles.obj と Karatoise1.obj の両方が複数出現することがわかります。Charles と Karatoise1 がメインの Karatoise で定義されるように、クラスの作成を移動するとします。cpp と Player.cpp は、それらが存在することを受け入れません。Karatoise1 と Charles がお互いを見ることができるようにファイルを設定する方法を教えてください。
4 に答える
ヘッダー ファイルでオブジェクトを作成したり、グローバル変数を定義したりしないでください。変数を宣言するために使用extern
し、cpp ファイルで定義します。
どのソース ファイルからでもアクセスできるように、クラスを定義し、ヘッダーでグローバル変数を宣言する必要があります。
// Player.h
// Define a Player class
class Player {
// blah blah
};
// Declare a Player object
extern Player Charles;
次に、1 つのソース ファイルでオブジェクトを定義する必要があります。これにより、定義が 1 つだけになります。これは「1 つの定義ルール」として知られています。
// Player.cpp
#include "Player.h"
// Define the Player object declared in the header
Player Charles;
ご覧のとおり、ソース ファイルにすべてが含まれているため、他のソース ファイルからはまったくアクセスできません。すべてがヘッダーに含まれているため、オブジェクトは、ヘッダーを含む各ソース ファイルによって複数定義されていました。
次の問題は、各ヘッダーが他のヘッダーを含めようとすることですが、これは不可能です。ここでは、次の 3 つの状況が考えられます。
- クラス定義で他のクラスについて言及する必要がなく、ソース ファイル内でのみ必要な場合は、すべて問題ありません。ソース ファイルから他のクラス ヘッダーをインクルードするだけです。
- クラス定義に他のタイプのオブジェクトを含める必要がある場合は、このヘッダーから他のヘッダーを含める必要があります。もちろん、両方のクラスにもう一方のクラスを含めることは不可能であるため、両方のヘッダーを相互に含める必要はありません。
- クラス定義で他のクラスに言及する必要がある場合 (そのクラスへの参照またはポインターであるメンバーがあるか、パラメーターまたは戻り値の型として受け取るメンバー関数があるため)、他のクラスを宣言する必要があります。
これが3番目のケースの例です
// Player.h
class Karatoise; // Just a declaration, not the full class definition
class Player {
Karatoise & k_ref; // OK
Karatoise * k_ptr; // OK
Karatoise do_something(); // OK
do_something(Karatoise); // OK
Karatoise k_obj; // Not OK: needs full class definition
};
あなたのフレーズにエラーがあります: Karatoise.cpp includes Player.h and Player.cpp includes Karatoise.h .
循環インクルードを作成してはなりません。で作成した場合Player.h
:
#include Karatoise.h
したがって、逆の組み込みを行ってはなりません。片道のみ。