2011-09-28 25 views
6

Estaba leyendo un libro de estructuras de datos anterior y decía que cuando está haciendo la clase de programación de plantillas debe incluir el .cpp al final del archivo .h.Incluyendo .cpp al final del archivo de encabezado de plantilla

Hasta donde yo sé, tiene que hacer implementaciones de funciones completas en su archivo .h para cualquier función de miembro de clase de plantilla, es debido a la forma en que funciona el compilador de plantillas.

Las únicas funciones que me enseñaron se pueden poner en un archivo de implementación para una clase de plantilla en las funciones de especialización de plantillas, es decir: template<> Class<Type>::function_name().

¿Por qué este libro sugeriría incluir el .cpp al final de .h? ¿Es esto solo una forma de separar las implementaciones en diferentes archivos mientras los compilamos con el encabezado? y si es así, ¿dónde colocarías especializaciones reales? Supongo que no podrían entrar en el .cpp incluido en el encabezado.

Respuesta

9

Lo más probable es que el autor prefiera tener declaración y definición en diferentes archivos, puedo adivinar que es porque hace que sea más fácil saltar entre declaraciones y definiciones.

Pero tener la extensión de archivo "cpp" es un poco confuso. Por lo general, esos archivos se llaman "ipp" para "C++ en línea".

+2

Nunca he visto en mi vida estos archivos con el nombre 'ipp' –

+0

@JohnDibling: Todo ha terminado. Las preguntas sobre eso fueron planteadas aquí en SO antes. –

+0

ver http://stackoverflow.com/questions/543507/in-the-c-boost-libraries-why-is-there-a-ipp-extension-on-some-header-files –

3

Probablemente este sea el viejo lenguaje, y creo que su análisis de separación de implementación y declaración es correcto. Cuando se escribió este libro en particular, el autor probablemente pensó en un archivo cpp como el archivo donde residían las definiciones, y en archivos h como los archivos donde residían las declaraciones. Poner especializaciones explícitas reales en el archivo anterior, naturalmente, sería letal (o al menos inútil) para el vinculador debido a las definiciones repetidas. Hoy en día, evitaría nombrar el archivo de definiciones .cpp.

0

Por lo que sabe que tiene que hacer implementaciones de funciones completo en su archivo .h de las funciones miembro de clase de plantilla - que es debido a la forma en que funciona el compilador las plantillas.

Puede ser que el libro suponga que tiene implementaciones de funciones completas en su archivo .cpp.

Si las especializaciones completas se encuentran en el archivo cpp, no se deben incluir en el archivo de encabezado. Lo más probable es que no se compile si lo hiciste. Debido a que el compilador verá múltiples definiciones de la misma función, el archivo de encabezado generalmente se incluirá en múltiples archivos fuente.

0

Si desea utilizar una plantilla, toda la definición de la plantilla debe estar visible en la TU que ejemplifica la plantilla. Entonces, simplemente podría poner definiciones completas en el archivo de encabezado.

Es solo si realmente desea mantener la definición de clase y los cuerpos de funciones de miembro de clase separados, entonces podría estar tentado de poner esas definiciones de funciones en un archivo separado. Sin embargo, la regla anterior aún se aplica, por lo que deberá incluir el archivo separado junto con el encabezado para que cualquiera pueda usar la plantilla.

Es una cuestión de gusto. Si los cuerpos de la función miembro son cortos, también podría definirlos en línea. También tenga en cuenta que las funciones que se definen dentro de la definición de la clase se declaran implícitamente inline, mientras que debe especificarlo explícitamente si escribe los cuerpos por separado.

Una plantilla parcialmente especializada sigue siendo una plantilla, por lo que se aplican las mismas reglas.

Una plantilla de clase completamente especializada es sólo una clase ordinaria, por lo tratas como tal es:

// FooInt.hpp 
template <typename> class Foo; 
template <> class Foo<int> 
{ 
    // your class here 
}; 

Una cosa que pueda haber tenido en cuenta es "plantilla de instancias explícita", al estilo de template class Foo<int>;. Eso es otra cosa; deja un comentario si estás interesado en usar eso.

1

En primer lugar, no hay ninguna regla que usted tiene que tener las implementaciones de los plantillas en el archivo de .h (o .hpp o .hh); de hecho, para cualquier cosa pero las plantillas más simples, recomendaría no hacerlo. Hace tiene que incluir la implementación, independientemente del archivo. Lo que probablemente el autor de tenía en mente era poner la implementación en un archivo .cpp , e incluir eso. Sin embargo, recomendaría encontrar un nombre diferente, , ya que la mayoría de las personas (y algunos IDE) supondría que debería compilar todos los archivos .cpp. Una convención común donde .cc y .hh son las extensiones usuales para fuentes y encabezados es .tcc para las implementaciones de la plantilla ; en un mundo de Windows (donde .cpp es casi universal), Recomendaría algo como .tpp.

Tenga en cuenta que las primeras implementaciones de plantillas requerían que la implementación estuviera en un .cpp. Sin embargo, estas implementaciones no requieren (ni permiten) que se incluyan; el compilador buscó la .cpp (o .cc) correspondiente al archivo .hpp (o .hh) en la que la definición de clase de plantilla o declaración de la función aparecieron, y genera un archivo de origen ficticia que incluyó (y cualquier otra cosa, que era necesario)

Cuestiones relacionadas