Schi Heil と叫ぶために

hiroakiuno's blog

C++ヘッダファイルのパターン

C++ Header File Include Patterns
ふと見つけたC++のヘッダファイルに関するページ。パターンというほど体系的なものではないかもしれないが、せっかくなのでメモしておこう。

  1. A header file should be included only when a forward declaration would not do the job.
  2. The header file should be so designed that the order of header file inclusion is not important.
  3. The header file inclusion mechanism should be tolerant to duplicate header file inclusions.

1. 前方宣言ではダメなときに初めてヘッダファイルをインクルードしよう

あるクラスを利用するからといってすぐにそのヘッダファイルをインクルードするのではなく、まずは前方宣言で十分じゃないか検討しようという内容。上記サイトのサンプルプログラムでは、a.h 内ではクラスCやクラスDをポインタとしてしか利用していないため、c.h や d.h をインクルードするのではなく前方宣言にとどめている。不要なヘッダファイルをインクルードしないというのは重要だ。

2. ヘッダファイルはインクルードする順番を気にしなくてもすむように設計しよう

あれ?ほとんど変えていないのに急にコンパイルが通らなくなった…。というあの体験。その原因は意外にも今回変更した部分ではなく、インクルードしたファイル自体の問題だったいうことは多い。適当にたくさんのファイルがインクルードされていたのでたまたまコンパイルが通っていたのだが、他を変えたときに後々発覚する依存関係の問題。解析していくと原因はさらに中でインクルードしている部分だったり。でもそのファイル俺が書いたんじゃないんだけどなーとか。

Also note that a.h has been included as the first header file in a.cpp This will make sure that a.h does not expect a certain header files to be included before a.h. As a.h has been included as the first file, successful compilation of a.cpp will ensure that a.h does not expect any other header file to be included before a.h. If this is followed for all classes, (i.e. x.cpp always includes x.h as the first header) there will be no dependency on header file inclusion.

a.h が a.cpp で一番最初にインクルードされるように書く。それを全てのクラス(ファイル)で守ることで依存関係の問題が軽減できるという教え。
「必要十分」なヘッダファイルを作成することは重要。その技術を形式的にパターン化してしまえる方法。経験的になんとなくやっていたことではあるがこう言われるとしっくりくる。

3. ヘッダファイルを書くときは多重にインクルードしてもよいように気を配ろう

上記サイトではよくある #ifndef マクロ の薦めとどまっているが、それに加えて何をヘッダファイルに書くのかの理解は重要だ。
例えば私は、using文はヘッダファイルでは使わないように心がけている。そのクラスや関数を利用することと引き換えに名前空間の仕組みを犠牲にしてしまうからだ。つまりソースファイル(定義)ではusingを用いるが、ヘッダファイル(宣言)ではusingを用いずスコープ解決演算子を用いる。一人で書く場合だと単なるこだわりに過ぎず、むしろめんどくささの方が強いが、多人数で書いたり、それをライブラリとして提供する場合なんかは必須の心がけだと思いますがどうでしょうか?