インライン函数の存在意義


函数をインライン化すると処理時間を短縮できることがあります。 といっても、必ず短縮できる訳ではなく、逆転することだってある。 じゃあどんな場合に短縮できるのか、っていうと、コンパイラーによります。 それどころか、コンパイラーがインライン化しないと 決定してしまうことだってあります。

処理時間を別にすれば、インライン化した場合としない場合とで 動作は同じであるべきですし、また、実際そうなっています。

処理時間を測定してみると効率上非常に重要な部分で、 しかもインライン化すると改善される、という場合ならば当然そうすべきでしょう。 以後の議論は、処理時間の上で実質的な差がない場合に限定します。


リンク互換性

例えば、クラスHogeの中に変数Ageがあるとします。

まず、Ageをpublic変数にすることは、相当の理由がない限り禁止です。 どうして、って、Ageをクラスの外から自由に書き換えられるんじゃ、 クラスを導入した意味が半減してしまいますからね。

という訳で、大原則はprivate変数にすること。 派生クラスを全部自分で管理できるのならば、protectedにしたくなることも あるかも知れないけど、これも、そうしなければならない理由をはっきり 言えないのならば、やめといた方がいいですね。

余談ですけど、書き換えを禁止できるのならば、クラスの外から参照することは 許可しても安全なんですよね。これができないのがC++の不自由なところ。 ちなみにEiffelなんかはちゃあんとそうなっていますぞ。

んで、次のようなプログラムが氾濫するんですね。

        class Hoge
        {
        public:
                int GetAge(void) const { return Age; };
                void SetAge(int age) { Age = age; };
        private:
                int Age;
        }

こんな具合に、

変数の数だけSetとGetの組ができる

という状況です。なあんだ、これじゃAgeをpublicにしたのと変わらないじゃん。 つまり、public変数にして

        Hoge    hoge;
        hoge.Age = 100;

とする代わりに

        hoge.SetAge(100);

とすることが自由にできてしまう訳で、実質的に情報隠蔽がなされていないのです。

それでもあえてprivate変数にしていちいちSet/Get函数を用意するのは、 ひとつには、変な書き換えを制禦できるという利点があるからです。 例えば上記の例で、

        void SetAge(int age) {
                if (0 <= age) {
                        Age = age;
                }
        };

というようにして負値にすることを排除すれば、「Ageは0以上であるべし」という 不変表明を保つことができるのです。

Ageって「あげ」じゃなくって「エイジ(年齢)」だよ

って訳で、年齢が負になるのは何かおかしいんですね。 Age以外にも変数があったとして、Ageと矛盾しないようにSetAge()の中で 適切に更新するとすれば、もっと込み入った不変表明も保てることになります。

それはさておき、こういう小さな函数はインラインにしたくなりますが、 そうすると修正するたびに

#include "hoge.h" しているソースを全部コンパイルしなおす

ということになります。

hoge.hを自分が作っているアプリケーションの中でのみ使うのならば、 これはあまり問題になりません。 まあ、巨大なアプリケーションで、コンパイルに30分もかかるようならば ちょっと考えなければなりませんが。

問題は、これがライブラリーの形でほかのアプリケーションから使われる場合です。 というのも、ライブラリーを改訂したときは、できればアプリケーションの方は そのままにして、ライブラリーだけ差し替えてちゃんと動いて欲しいからなんですね。

ライブラリーのhoge.hのSetAge()がインラインだと、実際にはそのコードは アプリケーションの方に展開されていますから、 こちらもコンパイルし直さなければならないのです。 こういうのを、リンク互換性が保たれていないと言います。

(註)

本当にライブラリーだけ差し替えて大丈夫なようにするには、 もっといろんなことを考慮する必要があります。 インターフェイス・クラスというものを導入するのも有効ですが、 このあたりの話はまた次の機会に。