2009-07-30 11 views
79

¿Cuáles son las ventajas de tener declaraciones en un archivo .inl? ¿Cuándo necesitaría usar el mismo?Importancia de un archivo .inl en C++

+2

FWIW, odio los archivos .inl. ¿Por qué dividir tu código más de lo necesario? – Shog9

+9

@ shog9: para separar la interfaz de la implementación. Siempre he odiado C# y el archivo Java porque es muy difícil leer la interfaz debido a todos los detalles de implementación de messey. –

+7

@Martin - lamentablemente C++ nos da una mala combinación de ambos mundos: la interfaz y parte de la implementación en el encabezado, el resto de la implementación en el archivo .cpp. Incluso si evitas las funciones en línea (o las pones en archivos .inl) tienes que llenar la interfaz con los molestos detalles de los miembros privados, a menos que puedas usar religiosamente el idioma pimpl. –

Respuesta

99

.inl archivos nunca son obligatorios y no tienen significado especial para el compilador. Es solo una forma de estructurar tu código que proporciona una pista a los humanos que podrían leerlo.

utilizo .inl archivos en dos casos:

  • Para las definiciones de las funciones en línea.
  • Para definiciones de plantillas de funciones.

En ambos casos, puse las declaraciones de las funciones en un fichero de cabecera, que se incluye por otros archivos, entonces el archivo #include.inl en la parte inferior del archivo de cabecera.

Me gusta porque separa la interfaz de la implementación y hace que el archivo de encabezado sea un poco más fácil de leer. Si le importan los detalles de implementación, puede abrir el archivo .inl y leerlo. Si no lo haces, no tienes que hacerlo.

+1

De hecho, se trata principalmente de separar la interfaz de la implementación. –

+0

También he visto utilizar .ipp y .ixx para las definiciones en línea y .tpp y .txx para la plantilla uno. – AProgrammer

+0

Por ejemplo, la biblioteca GNU Standard C++ utiliza '.tcc' para los archivos de implementación de plantillas. – musiphil

3

En mi experiencia, los archivos .inl se utilizan para definir funciones en línea. Cuando están en un archivo .inl, el archivo se puede incluir en un encabezado para obtener funciones en línea y en un archivo .c para obtener definiciones de funciones regulares.

De esta forma, la misma fuente puede funcionar más fácilmente con compiladores que no tienen soporte de función en línea, así como compiladores que sí lo hacen.

Se usan generalmente con código C directo, no a menudo con código C++, ya que todos los compiladores C++ admiten funciones en línea.

+0

No veo el sentido de hacer esto solo para obtener soporte de C. Para C, simplemente condicionalmente '#define inline static', y define tus funciones en línea en el encabezado. –

+0

Supongo que esto evita que múltiples copias de la misma función terminen en el binario. Solo digo que he visto archivos .inl usados ​​de esta manera, no es que sea la única técnica (o incluso la mejor). –

1

Creo que es solo una convención de nomenclatura para un archivo de "encabezado" que incluye código en línea. es para que los archivos .h puedan contener definiciones y los archivos .inl contengan código en línea que es necesario para las plantillas.

No belive hay algo más que una convención de nombres para hacer la finalidad del fichero clara

24

Dado que nadie más ha mencionado:

El uso de archivos .INL para almacenar sus funciones en línea puede ser útil para acelerar compilaciones.

Si solo incluye las declaraciones (.h) donde necesita declaraciones, y solo incluye las implementaciones en línea (.inl) donde las necesita (es decir, probablemente solo en .cpp y otros archivos .inl, no .h's), puede tener un efecto beneficioso en las dependencias de su encabezado.

Esto puede ser una gran victoria en proyectos más grandes con muchas clases interactuando.

+3

+1: el mundo es definitivamente un lugar diferente cuando administra millones de líneas de código y miles de archivos. – gatorfax

+0

, por lo que nunca debe incluir .inl en archivos de encabezado? Siempre tuve la sensación de que .inl debería colocarse en la parte inferior de los archivos de encabezado, ya que las funciones en línea requieren que la declaración y la implementación sean alcanzables a la vez. – Icebone1000

+1

Icebone1000 no todos los módulos que incluyen el encabezado necesariamente quieren usar las funciones en línea, por lo que no necesitan que se lean las implementaciones, no se requiere que estén presentes si no se usan. –

66

Nick Meyer tiene razón: Al compilador no le importa la extensión del archivo que está incluyendo, entonces cosas como ".h", ".hpp", ".hxx", ".hh", ". inl "," .inc ", etc. son una convención simple, para dejar en claro qué se supone que contienen los archivos.

El mejor ejemplo son los archivos de encabezado STL que no tienen extensión alguna.

Normalmente, ".inl "archivos contienen línea código (de ahí el" .INL "extensión).

Esos archivos" archivos .INL" son una necesidad cuando se tiene un ciclo de dependencia entre cabecera código.

Para ejemplo:

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

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

Y:

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

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

no hay manera de que usted tendrá que compilar , incluido el uso de la declaración directa.

La solución es entonces para romper definición y ejecución en dos tipos de archivos de cabecera:

  • hpp para la declaración de cabecera/definición
  • inl para la implementación de cabecera

que se descompone en el siguiente ejemplo:

// A.hpp 

struct B ; 

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

Y:

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

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

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

Y:

// B.hpp 

struct A ; 

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

Y:

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

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

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

De esta manera, se pueden incluir archivos que sea ".INL" que necesita en su propia fuente, y trabajará.

Nuevamente, los nombres de los sufijos de los archivos incluidos no son realmente importantes, solo sus usos.

+3

Esto explica el beneficio real (o la necesidad) de la separación, y debería haberse elegido como la respuesta. – musiphil

+0

Si la función no estuviera en línea, ¿usaría el archivo .cpp estándar para la parte de implementación? – Bublafus

+0

@Bublafus: 'Si la función no estuviera en línea, ¿usaría un archivo .cpp estándar para la parte de implementación?': Posiblemente. Las plantillas son ejemplos de código que normalmente no se pueden ocultar en archivos .CPP, por lo que en ese caso, el archivo .INL sería obligatorio. – paercebal

Cuestiones relacionadas