C ++での.inlファイルの重要性


108

.inlファイルで宣言を行うことの利点は何ですか?いつ使用する必要がありますか?


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

10
@ shog9:インターフェイスを実装から分離する。すべてのメッシー実装の詳細のためにインターフェースを読むのが難しいので、私は常にC#とJavaファイルを嫌っていました。
マーティンヨーク

8
@Martin-残念ながら、C ++は両方の世界の悪い組み合わせを提供します-ヘッダーとインターフェイスの実装の一部、.cppファイルの残りの実装。インライン関数を回避する(または.inlファイルに配置する)場合でも、pimplイディオムを忠実に使用することができない限り、プライベートメンバーの厄介な詳細でインターフェイスを混乱させる必要があります。
マイケルバー

5
ええ、ヘッダがインターフェースと実装を分けるという議論を理解したことはありません。彼らは明らかにそうではありません。インターフェイスには、すべてのプライベートメンバーを含めることはできません。
2009

@LokiAstari:公平を期すために、Java / C#には、インターフェースの概要を自動的に提供する非常に優れたツールがあります。C ++では、コンピュータで完全に解決できる問題を手動で解決する必要があります。
bluenote10

回答:


139

.inlファイルは必須ではなく、コンパイラにとって特別な意味はありません。コードを構造化する方法の1つであり、それを読む可能性のある人間にヒントを提供します。

次の.inl2つの場合にファイルを使用します。

  • インライン関数の定義について。
  • 関数テンプレートの定義について。

両方の場合において、私は私、他のファイルが含まれているヘッダファイル内の関数の宣言を入れたヘッダファイルの下部にあるファイル。#include.inl

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


2
実際、それは主にインターフェースを実装から分離することに関するものです。
Pavel Minaev、2009

1
インライン定義に.ippと.ixxを使用し、テンプレート1に.tppと.txxを使用することも確認しました。
AProgrammer 2009

1
たとえば、GNU標準C ++ライブラリは.tccテンプレート実装ファイルに使用します。
ムシフィル2013年

1
@NickMeyer glmは、前述の方法とまったく同じ方法で.hppと.inlを使用します。知っておくと良いです。すばらしい答えをありがとう:)
legends2k

それはヘッダーのようなものですか?
アーロンフランケ

90

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」ファイルを独自のソースに含めることができ、機能します。

繰り返しになりますが、インクルードされるファイルのサフィックス名は実際には重要ではなく、その用途だけが重要です。


5
これは、分離の真の利点(または必要性)を説明し、答えとして選択されるべきでした。
musiphil

関数がインラインでなかった場合、実装部分の標準.cppファイルを使用しますか?
ブブラフス

@Bublafus::たぶんIf the function were not inline, you would you standard .cpp file for the implementation part?。テンプレートは、通常.CPPファイルで非表示にできないコードの例であるため、その場合、.INLファイルは必須です。
paercebal

32

他の誰もそれを言及していないので:

.inlファイルを使用してインライン関数を格納すると、コンパイルの高速化に役立ちます。

宣言が必要な場所に宣言(.h)のみを含め、必要な場所にインライン実装(.inl)のみを含める場合(つまり、おそらく.cppと他の.inlファイルのみで、.hは含まない)、ヘッダーの依存関係に対する有益な効果。

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


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

したがって、ヘッダーファイルに.inlを含めないでください。インライン関数は宣言と実装に同時に到達できる必要があるため、常に.inlをヘッダーファイルの最後に置くべきだと感じていました。
Icebone1000 2013年

1
Icebone1000は、ヘッダーを含むすべてのモジュールが必ずしもインライン関数を使用することを望んでいるわけではないため、実装を読み込む必要はなく、使用されていない場合に存在する必要はありません。
アンディJブキャナン2013年

1
コンパイラが翻訳単位を含めて組み合わせるには、より多くの作業を行う必要があるため、どのようにして高速化できるのかわかりません。
ニコス

1
@ニコス彼はすべてのインライン関数をヘッダーファイルに入れるよりも速くなると思いました。
CoffeeTableEspresso

3

私の経験では、.inlファイルはインライン関数の定義に使用されています。それらが.inlファイルにある場合、ファイルをヘッダーに含めてインライン関数を取得したり、.cファイルに含めて通常の関数定義を取得したりできます。

このようにして、同じソースは、インライン関数をサポートしていないコンパイラーと同様に、インライン関数をサポートしていないコンパイラーでより簡単に機能します。

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


Cのサポートを得るためだけにこれを行う意味はないと思います。Cの場合、条件付き#define inline staticで、ヘッダーにインライン関数を定義します。
Pavel Minaev、2009

これにより、同じ関数の複数のコピーがバイナリになってしまうのを防ぐことができます。この方法で使用された.inlファイルを見たことがあると言っているだけで、それが唯一の手法(または最高の手法)であるとは限りません。
マイケルバー

1

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

ファイルの目的を明確にするための命名規則以外に何かがあるとは思えません

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.