2009-07-30 39 views
79

.inlファイルに宣言を入れることの利点は何ですか?いつ私は同じものを使用する必要がありますか?C++での.inlファイルの意義

+2

FWIW、嫌いな.inlファイル。なぜあなたのコードを必要以上に分割するのですか? – Shog9

+9

@ shog9:実装からインタフェースを分離する。私はいつもC#とJavaファイルを嫌っていました。なぜなら、すべての面倒な実装の詳細のためにインターフェイスを読みにくいからです。 –

+7

@Martin - 残念なことにC++は、ヘッダー内のインターフェイスと実装の一部、.cppファイル内の実装の残りの部分の両方の悪い組み合わせを私たちに与えます。インライン関数を避ける(または.inlファイルに入れる)場合でも、pimplイディオムを宗教的に使うことができない限り、プライベートメンバーの厄介な内容でインターフェイスを乱雑にする必要があります。 –

答えて

99

.inlファイルは必須ことは決してありませんし、コンパイラに特別な意味を持っていないファイルの目的を明確にする命名規則よりも、それより何がある信じないでください。これは、コードを構造化して人間にそれを読むかもしれないヒントを提供する単なる方法です。インライン関数の定義については

  • 私は2例で.inlファイルを使用しています。

  • 機能テンプレートの定義。両方の場合において

、私は私は、ヘッダファイルの下部に.inlファイルを#include、他のファイルが含まれているヘッダファイル内の関数の宣言を置きます。

インターフェイスが実装から分離され、ヘッダーファイルが少し読みやすくなります。実装の詳細が気になる場合は、.inlファイルを開いて読むことができます。あなたがしなければ、あなたはする必要はありません。

あなたのインライン関数を格納する.inlファイルの使用は、コンパイルをスピードアップするために有用であることができます誰もがそれを言及していないので

+1

実際、実装とインターフェイスを分離することがほとんどです。 –

+0

インライン定義には.ippと.ixxが使用され、テンプレート1には.tppと.txxが使用されています。 – AProgrammer

+0

例えば、GNU標準C++ライブラリはテンプレート実装ファイルに '.tcc'を使います。 – musiphil

3

私の経験では、.inlファイルを使用してインライン関数を定義しています。 .inlファイルに入っているときは、ファイルをヘッダーに組み込んでインライン関数を、.cファイルを使用して正規の関数定義を得ることができます。

このようにして、同じソースは、インライン関数をサポートしていないコンパイラだけでなく、コンパイラでも簡単に動作します。

通常、すべてのC++コンパイラはインライン関数をサポートしているため、C++コードではよく使用されません。

+0

ちょうどCのサポートを得るために、これを行う上でのポイントがありません。 Cでは、条件付きで '#define inline static'を定義し、ヘッダーにインライン関数を定義します。 –

+0

これは、同じ関数の複数のコピーがバイナリで終わるのを避けると思います。私はちょうど私がこの方法で使用された.inlファイルを見てきたと言っているだけで、それが唯一のテクニックではありません。 –

1

「ヘッダー」ファイルの名前付け規則は、インラインコードが含まれていると思います。 .hファイルに定義を含めることができ、.inlファイルにはテンプレートに必要なインラインコードが含まれています。

私は

24

宣言が必要な箇所にのみ宣言(.h)を組み込み、インライン実装(.inl)が必要な場所にのみ(つまり、おそらく.cppや.inlファイルで、.hのものではない)ヘッダーの依存関係に有益な効果をもたらすことができます。

これは、多くの相互作用するクラスを持つ大きなプロジェクトで大きな勝利になる可能性があります。

+3

+1:世界は、何百万行ものコードと何千ものファイルを管理しているときは、まったく別の場所です。 – gatorfax

+0

ヘッダーファイルに.inlを含めないでください。インライン関数は宣言と実装が同時に到達可能である必要があるため、ヘッダファイルの最後に.inlを置くべきだという気持ちが常にありました。 – Icebone1000

+1

Icebone1000ヘッダーを含むすべてのモジュールが必ずしもインライン関数を使用するとは限らないため、実装を読み込む必要はなく、使用されていなければ存在する必要はありません。 –

66

Nick Meyerが正しい:コンパイラは、あなたが含むファイルの拡張子を気にしないので、 ".h"、 ".hpp"、 ".hxx"、 ".hh"、 "。 inl "、" .inc "などは、ファイルに含まれる内容を明確にするための簡単な規則です。

最も良い例は、拡張子のないSTLヘッダーファイルです。

通常、 "。INL「(.inlファイルはインラインコードので、含まれていません」「拡張子を)。

これらのファイル」あなたはヘッダコード間の依存サイクルを持っているとき.inl」ファイルが必要です。のために

を例:

// A.hpp 
struct A 
{ 
    void doSomethingElse() 
    { 
     // Etc. 
    } 

    void doSomething(B & b) 
    { 
     b.doSomethingElse() ; 
    } 
} ; 

そして:

// B.hpp 
struct B 
{ 
    void doSomethingElse() 
    { 
     // Etc. 
    } 

    void doSomething(A & a) 
    { 
     a.doSomethingElse() ; 
    } 
} ; 

あなたはそれをコンパイルしています方法はありません前方宣言の使用を含む。

ソリューションは、ヘッダファイルの2種類に定義および実装を打破するために、その後です:ヘッダの宣言/定義について

  • hpp
  • inlヘッダの実装のためのダウンに侵入

次の例:

// A.hpp 

struct B ; 

struct A 
{ 
    void doSomethingElse() ; 
    void doSomething(B & b) ; 
} ; 

そして:

// A.inl 
#include <A.hpp> 
#include <B.hpp> 

inline void A::doSomethingElse() 
{ 
    // Etc. 
} 

inline void A::doSomething(B & b) 
{ 
    b.doSomethingElse() ; 
} 

そして:

// B.hpp 

struct A ; 

struct B 
{ 
    void doSomethingElse() ; 
    void doSomething(A & a) ; 
} ; 

そして:

// B.INL 
#include <B.hpp> 
#include <A.hpp> 

inline void B::doSomethingElse() 
{ 
    // Etc. 
} 

inline void B::doSomething(A & a) 
{ 
    a.doSomethingElse() ; 
} 

この方法で、あなたがあなた自身のソースに必要なものは何でも ".inl" ファイルが含まれ、それができ働くでしょう。

この場合も、インクルードされたファイルの接尾辞名は、実際には重要ではなく、その使用のみが重要です。

+3

これは分離の本当の利益(または必要性)を説明し、答えとして選択されているはずです。 – musiphil

+0

関数がインラインでない場合は、実装部分の標準.cppファイルですか? – Bublafus

+0

@Bublafus: '関数がインラインでない場合、実装部分の標準.cppファイルでしょうか?':おそらく。テンプレートは、通常.CPPファイルに隠れることのできないコードの例です。この場合、.INLファイルは必須です。 – paercebal

関連する問題