動作確認
C++ Builder XE4
以下のヘッダーファイルがあるとする (良い設計の場合は、ないはずだが)
extra1.h
#ifndef _EXTRA1_H
#define _EXTRA1_H
enum COLOR_e {
COLOR_RED,
COLOR_BLUE,
COLOR_GREEN
};
#endif
extra2.h
#ifndef _EXTRA2_H
#define _EXTRA2_H
enum COLOR_e {
COLOR_RED,
COLOR_BLUE,
COLOR_GREEN
};
#endif
上記の2つのヘッダーファイルのincludeの仕方によって、COLOR_REDなどの重複定義が起きてしまう。
case 1 (問題なし)
- Unit1.cpp
- #include "extra1.h"
- Unit2.cpp
- #include "extra2.h"
Unit1.cppからはextra2.hをincludeする経路がなく、Unit2.cppからもextra1.hをincludeする経路がないので、重複定義にはならない。
case 2 (問題なし)
- Unit1.h
- #include "extra1.h"
- Unit2.h
- #include "extra2.h"
こちらもcase1と同じで、お互いが一方のextraX.hをincludeする経路がないので問題ない。
case 3 (問題あり)
- Unit1.h
- #include "extra1.h"
- Unit2.h
- #include "extra2.h"
- Unit2.cpp
- #include "Unit1.cpp" // ------------------
Unit2.cppからUnit1のフォームなどを使いたとして"Unit1.cpp"を追加した途端に重複定義が発生する。
対策
C++のみのコード
以下のような方法がありそう。
- namespaceで切り分ける
- 重なる定義だけ別ヘッダファイル(インクルードガード付き)に抽出
C++/C 混在コード
ただし、C側のプロジェクトでは重複が発生しないことが保証されていて、C++側のプロジェクトで重複が起きてしまうことがある場合。
以下のような方法がありそうか。
- 重なる定義だけ別ヘッダファイル(インクルードガード付き)に抽出
- #include "Unit1.cpp"を回避する。 (前方宣言をすれば良かったか、など整理ができていない)
- 重なる定義部分だけ {#ifndef XXX / #define XXX / 定義} にする