C++で多重インクルードを防ぐ方法

出典: YKAwiki

例えば。クラスAの定義がA.hに、関数の実体がA.cppに書いてあって、クラスBの定義がB.hに、関数の実体がB.cppに書いてあるとします。普通、このような場合はA.cppからA.hをインクルード、B.cppからB.hをインクルードします。そして、main関数の書いてあるmain.cppからはA.hとB.hをインクルード。これで大抵の場合はコンパイル・実行できます。

ところが、この状態から、「クラスAの関数をクラスBの関数内で使いたいなぁ」と思って、B.hでA.hをインクルードするとコンパイラたんが『アンタ、多重インクルードしてるわよ!』って怒ってきます。さぁ困りました。

なぜ『多重インクルード』が起こったのか? 実際に問題が起こったのはmain.cppのコンパイル時です。このケースでは、main.cppから見ると、main.cppからインクルードしたA.hのクラスAの定義と、そしてB.hからインクルードしたA.hのクラスAの定義がバッティングしているのです。つまり、main.cppからは二回A.hを読み込んだことと同じになっているのです。

こんなときどうするかというと、新しいhoge.hを作って、そこでA.hとB.hをインクルードしてやります。こうすると、hoge.hにはA.hとB.hの内容が1回ずつ書いてあるのと同じことになります。あとは、hoge.hをA.cpp、B.cpp、main.cppでそれぞれインクルードしてやればOKです。

--- とりあえずヘッダー作ったら

#ifndef _HOGEHOGE_
#define _HOGEHOGE_

class HogeHoge{
};
#endif

って感じで囲んどけばOK。HOGEHOGEは一意の文字列にすべし。