C++中.inl文件的意义

Zuz*_*uzu 98 c++

在.inl文件中声明有什么好处?我什么时候需要使用相同的?

Nic*_*yer 129

.inl文件永远不是必需的,对编译器没有特殊意义.它只是构建代码的一种方式,它为可能读取它的人提供了一个提示.

.inl在两种情况下使用文件:

  • 有关内联函数的定义.
  • 用于函数模板的定义.

在这两种情况下,我把的功能的声明在头文件,它是由其它文件包括,那么我#include.inl在头文件的底部文件.

我喜欢它,因为它将接口与实现分开,使头文件更容易阅读.如果您关心实现细节,可以打开.inl文件并阅读它.如果你不这样做,你就不必这样做了.

  • 事实上,它主要是关于将接口与实现分离。 (4认同)
  • @NickMeyer `glm` 使用 .hpp 和 .inl 的方式与您上面提到的完全相同。很高兴知道,感谢您的出色回答:) (2认同)

pae*_*bal 82

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() ;
    }
} ;
Run Code Online (Sandbox Code Playgroud)

和:

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

    void doSomething(A & a)
    {
       a.doSomethingElse() ;
    }
} ;
Run Code Online (Sandbox Code Playgroud)

你无法编译,包括使用前向声明.

然后解决方案是将定义和实现分解为两种头文件:

  • hpp 用于标题声明/定义
  • inl 用于标头实现

其中分为以下示例:

// A.hpp

struct B ;

struct A
{
    void doSomethingElse() ;
    void doSomething(B & b) ;
} ;
Run Code Online (Sandbox Code Playgroud)

和:

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

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

inline void A::doSomething(B & b)
{
   b.doSomethingElse() ;
}
Run Code Online (Sandbox Code Playgroud)

和:

// B.hpp

struct A ;

struct B
{
    void doSomethingElse() ;
    void doSomething(A & a) ;
} ;
Run Code Online (Sandbox Code Playgroud)

和:

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

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

inline void B::doSomething(A & a)
{
   a.doSomethingElse() ;
}
Run Code Online (Sandbox Code Playgroud)

这样,您可以在自己的源中包含所需的任何".inl"文件,它将起作用.

同样,包含文件的后缀名称并不重要,只是它们的用途.

  • 这解释了分离的真正好处(或必要性),应该选择作为答案. (4认同)
  • 如果函数不是内联的,您会为实现部分提供标准的 .cpp 文件吗? (2认同)
  • @Bublafus:“如果函数不是内联的,您会为实现部分提供标准的 .cpp 文件吗?”:可能。模板是通常无法隐藏在 .CPP 文件中的代码示例,因此在这种情况下,.INL 文件将是强制性的。 (2认同)

And*_*nan 31

由于没有人提到它:

使用.inl文件存储内联函数对于加速编译非常有用.

如果只包含需要声明的声明(.h),并且只包含你需要它们的内联实现(.inl)(即可能只在.cpp和其他.inl文件中,而不是.h's),它可以有一个对标头依赖性的有益影响.

这对于具有许多交互类的大型项目来说是一个重大的胜利.

  • +1:当您管理数百万行代码和数千个文件时,世界绝对是一个不同的地方. (7认同)
  • Icebone1000 并非所有包含标头的模块都必须使用内联函数,因此它们不需要读入实现,如果不使用它们,则不需要存在。 (2认同)