最近、クラスのヘッダーファイルに関数を定義している物をよく見ます。
インライン関数にしたいのならともかく、明らかにインラインとならない物を
ヘッダーファイルに含めてもいいのでしょうか?
たしかこの場合はstatic属性扱いとなったように記憶しているのですが。
特に、本当にstaticな関数をヘッダーファイルに含めるとその実態が複数できてしまうと
思っていたのですが、最近のコンパイラやリンカはその辺は大丈夫なのでしょうか?
#pragma onceと最初にあったので、二重インクルードの心配はないのですが。
> インライン関数にしたいのならともかく、明らかにインラインとならない物を
> ヘッダーファイルに含めてもいいのでしょうか?
「明らかにインラインとならない物」というのはどういうことでしょうか?
例えば,
inline int func (void) { return 0; }
というコードでさえコンパイラはインライン化する必要はないです。
> たしかこの場合はstatic属性扱いとなったように記憶しているのですが。
ARMの頃はそうだったみたいですが,現在ではそのような扱いはなされません。
> 特に、本当にstaticな関数をヘッダーファ
イルに含めるとその実態が複数できてしまうと
> 思っていたのですが、最近のコンパイラやリンカはその辺は大丈夫なのでしょうか?
staticメンバ関数であれば,実体は一つです。
#internal-linkageを付ける方のstaticであれば,実体はたくさんできますが。
また,標準C++では実体は一つであることを要求しています。
ISO/IEC 14882:1998の7.1.2 Function specifiers 段落4
> An inline function with external linkage shall have the same address in all
translation units.
> A static local variable in an extern inline function always refers to the same
object.
> A string literal in an extern inline function is the same object in different
translation units.
コンパイラがちゃんと標準を守っているか否かは別問題ですが,
手元のVC++ 5.0で簡単に試したところでは,これらの条件を満たしていました。
読みやすいところでは,Effective C++の33項が参考になるでしょう。
ありがとうございます。
明らかにインラインとならない物とは、例えば仮想関数です。
これはインラインにしようがないはずです。
YuOさんのレスから、結局クラス定義は.hのみで全部行っていい、ということでしょう
か。
.hで定義、.cppでその実装というのはもう古いようですね。
まあ、ソースファイルが減るのは大歓迎ですね。
テンプレートはヘッダファイルに書かざるを得ない、というのもありますが、
実装が利用者に丸見えというのは良し悪しですね。
#export サポートしてくれないかなぁ…
そうですね。
ヘッダーファイルに実装まで入れてしまった場合の弊害ってそれくらいですね。
テンプレートは仕方ないとしても通常のクラスであくまでもインターフェイスの定義のみ
表に出したいのであれば、やっぱり実装はソースファイルに入れてヘッダーファイルから
外さないとだめですね。
まあ、簡単なゲッターやセッターは実装が見えても支障はないような気もしますけれど。
ところで、知識古いのか?さんには解決のチェックをしてもらいたいですね。
多分、知識古いのか?さんの質問に対しては答えになっていると思いますから。
チェックわすれてました。