問題は非常に単純です。依存関係のサイクルを持つことはできません。
// MainScheduler.h
#ifndef MAINSCHEDULER
#define MAINSCHEDULER
#include "Job.h"
class MainScheduler { friend class Job; };
#endif
// Job.h
#ifndef JOB
#define JOB
#include "MainScheduler.h"
class Job { friend class MainScheduler; };
#endif
MainScheduler.h を解析すると、次のようになります。
MAINSCHEDULER
は定義されていないため、解析が開始されます
- プリプロセッサが定義する
MAINSCHEDULER
- プリプロセッサには Job.h が含まれています
- は既に定義されているため
MAINSCHEDULER
、MainScheduler.h のインクルードをスキップします。
- からのトークンが含まれます
Job
- Job.h のインクルード終了
- からのトークンが含まれます
MainScheduler
これにより、コンパイラが確認する次のプリプロセッサ出力が生成されます。
// ignored #include "MainScheduler.h"
class Job { friend class MainScheduler; };
class MainScheduler { friend class Job; };
MainScheduler
これが、前方宣言を導入する前に、コンパイラが の定義にある不明なシンボルについて不平を言った理由ですJob
。
ヘッダー自体をサイクルに含めることはできません。また、前方宣言のみでメンバー関数と友達になることはできません。
Job.h を次のように書き換えることをお勧めします。
class MainScheduler; // forward declaration
class Job {
friend class MainScheduler;
public:
// whatever
};
クラス全体と仲良くなることで、前向きな宣言だけで逃げ出し、サイクルを断ち切ることができます。