【C++】ヘッダーの相互参照

ヘッダーの相互参照の問題

c++で以下のようにclass Aとclass Bでお互い参照したいときには、以下のように書くはず。

#ifndef _A_H_
#define _A_H_

#include "B.h"

class A{
  B* b;
}
#ifndef _B_H_
#define _B_H_

#include "A.h"

class B{
  A* a;
}

ところが、実際にコンパイルしてみると上記の書き方だとエラーになる。
何故かと言うと、

  1. A.hの中でB.hをincludeする
  2. includeしたB.hの中でA.hをincludeしなくてはいけないが、すでに_A_H_がdefineされているため読み込まれない。
  3. Aの宣言がされていないため、class Bの中でclass Aが不明の状態となりポインタを宣言できない。

ためである。
どちらのクラスも先に相手が宣言済みでないとコンパイルできない。
※ includeは指定したコードをそこに書くだけの単純な処理であることに注意。

前方宣言による解決

そんな場合には、以下のようにヘッダー内で相手のクラスの宣言だけしておけばよい。
クラスのインスタンスにはクラス定義が必要だが、ポインタを保持するだけであれば、そういう名前のクラスがあることさえ分かれば良い。
そのためにとりあえず宣言だけするのが前方宣言。

#ifndef _A_H_
#define _A_H_

//#include "B.h"
class B; // クラスBへの参照
class A{
  B* b;
}
#ifndef _B_H_
#define _B_H_

//#include "A.h"
class A; // クラスAへの参照
class B{
  A* a;
}