2010-02-08 12 views
27

Me gustaría empaquetar una biblioteca en la que estoy trabajando como una biblioteca de solo encabezado para que los clientes la utilicen más fácilmente. (Es pequeño y no hay realmente ninguna razón para ponerlo en una unidad de traducción separada) Sin embargo, no puedo simplemente poner mi código en los encabezados porque esto viola la regla de definición de C++. (Suponiendo que el encabezado de la biblioteca se incluye en varias unidades de traducción de un proyecto de cliente)¿Cómo creo una biblioteca de solo encabezado?

¿Cómo se modifica una biblioteca para que sea solo de encabezado?

Respuesta

45

Usted puede utilizar la palabra clave inline:

// header.hpp (included into multiple translation units) 

void foo_bad() {} // multiple definitions, one in every translation unit :(

inline void foo_good() {} // ok :) 

inline permite que el enlazador tomar simplemente una definición y desechar el resto.

(Como tal, si esas definiciones en realidad no coinciden, se obtiene una buena dosis de comportamiento indefinido ...!)


Como acotación al margen, las funciones miembro definidas dentro de un tipo de clase, están marcadas de forma implícita inline:

struct myclass 
{ 
    void i_am_inline_implicitly() 
    { 
     // because my definition is here 
    } 

    void but_i_am_not(); 
    void neither_am_i(); 
}; 

inline void myclass::but_i_am_not() 
{ 
    // but that doesn't mean my definition cannot be explicitly inline 
} 

void myclass::neither_am_i() 
{ 
    // but in this case, no inline for me :(
} 
+4

+1 de mí. Esto es casi todo en línea significa compiladores modernos. –

+0

Nitpick: no permite la ruptura de ODR; permite que la función se defina múltiples veces. Las definiciones todavía tienen que coincidir. –

+0

@BillyONeal: Un buen nitpick. Editado – GManNickG

1

Utilice protectores de cabecera para las piezas que se compilan en un solo lugar.

+4

Las protecciones de encabezado solo funcionan por unidad de traducción. – GManNickG

+0

@GMan: ¿Qué más necesitas? –

+8

Bueno, no sé ustedes; pero mis proyectos consisten en más de un archivo. – GManNickG

6

guardias uso de cabecera como Liz sugiere y no se olvide de poner "en línea" antes de que sus métodos de la función.

es decir

#ifndef MY_HEADER_H_ 
#define MY_HEADER_H_ 

inline RetType FunctionName(ParamType1 param1, ParamType2 param2) 
{ 
    // Function body 
    return retType; 
} 

#endif 
+0

Nitpick: en C++, no existe un método. Hay funciones de miembro y funciones de no miembros. –

+1

@BillyONeal Eso no es verdad; como puede leer en Stroustrups "El lenguaje de programación C++" en la página 587, las funciones de miembros virtuales son "a veces llamadas métodos". –

4

Además, creo que necesita para evitar cualquier uso de variables globales o variables estáticas en su código de cabecera de sólo-biblioteca.

Cuestiones relacionadas