- ベストアンサー
C++ヘッダの肥大化
最近、テンプレートクラスとインライン関数を多用しているため、ヘッダファイルの肥大化が気になります。 ヘッダが肥大化するとコンパイル時間も大きくなり、更にヘッダファイルの可読性も落ちてしまうと思います。 また、ライブラリ化するときはコードを隠蔽したいのですが、ほとんどがヘッダファイルに実体があるため隠蔽できません。 インライン関数やテンプレートクラス、テンプレート関数は必ずヘッダファイルに書く必要があるのでしょうか。 標準ヘッダファイルでは「*.cc」という実体コードをインクルードしているので、それに習うべきなのでしょうか。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
> インライン関数やテンプレートクラス、 > テンプレート関数は必ずヘッダファイルに書く必要があるのでしょうか。 両方とも、現実的に「使う場所」から実装が見えていないと意味がありませんので、 仮に分離して記述しても結果としてはそうなります。 インライン関数やテンプレートを使いまくれば、隠蔽はできません。 意味があるとすれば、実装をインタフェースから分離するという可読性位でしょうか。 ちなみに、言語的には拡張子を特に意識したりしませんので、 .hでも.hppでも.incでも.implでも.ccでも「includeする」以上隠蔽できないのは一緒です。 また、慣習として.ccは単に「C++のソース」を示すだけです。(.cpp等と同様) コンパイル時間の低減には、プリコンパイルヘッダ(PCH)が有効です。 VCや昨今のGCC等にはこういった機能があるかと思います。 templateは意味上で不可避なことも多いかもしれませんが、 inlineの多用は逆に性能を落とすケースもありますので、 getter/setter等のシンプルなものに限定するなどして、 「見られて困るような処理」がある大物は素直にソースにかかれてはどうでしょう。 # そういう関数は実際inline展開されていないことも多いでしょうし。 隠蔽したいなら、多少面倒でもpImplイディオムとかproxyとか使って、 実装とインタフェースを綺麗に分離する設計を考えた方が良いのではないかと思います。
その他の回答 (2)
- επιστημη(@episteme)
- ベストアンサー率46% (546/1184)
> 隠蔽したいなら、多少面倒でもpImplイディオムとかproxyとか使って、 > 実装とインタフェースを綺麗に分離する設計を考えた方が良いのではないかと思います。 pImpl/proxyで実装を分離したところで、実装部もtemplate使うしかないですよね。 ヘッダから実装を追い出すことにはならんのでは?
- επιστημη(@episteme)
- ベストアンサー率46% (546/1184)
> インライン関数やテンプレートクラス、テンプレート関数は必ずヘッダファイルに書く必要があるのでしょうか。 書かないとコンパイルできません。 > 標準ヘッダファイルでは「*.cc」という実体コードをインクルードしているので、それに習うべきなのでしょうか。 習う...ああ、"倣う"か。 ヘッダから"見掛け上"実装を追い払うことはできますね。
お礼
ありがとうございます。 見かけ上はヘッダから実装をなくしても、結果的にはヘッダに実装が必要なのですね。
お礼
詳細な回答、ありがとうございます。 >コンパイル時間の低減には、プリコンパイルヘッダ(PCH)が有効です。 これを使うとコンパイルできないことがしばしばあったのであまり使いたくなかったのですが、エラーの起きないプロジェクトでは使ってていこうと思います。 >inlineの多用は逆に性能を落とすケースもありますので、 このあたりのボーダーがよく分かりません。 3行程度の関数なら大丈夫でしょうか。 >隠蔽したいなら、多少面倒でもpImplイディオムとかproxyとか使って、 こちらは知りませんでした。 コピーコンストラクタや代入演算子の定義とか、かなり面倒になりそうですね。 また、参照を使うようなので、その部分の速度ロスが気になります。 なので、よほど隠蔽したいものを除いてはヘッダに記述するか別ファイルに記述し、インクルードという形をとりたいと思います。