*.h or *.hpp para sus definiciones de clase


Siempre he usado un archivo *.h para las definiciones de mi clase, pero después de leer un poco de código de la biblioteca boost, me di cuenta de que todos usan *.hpp. Siempre he tenido una aversión a esa extensión de archivo, creo que principalmente porque no estoy acostumbrado a ella.

¿Cuáles son las ventajas y desventajas de usar *.hpp sobre *.h?

 419
Author: gsamaras, 2008-09-30

20 answers

Aquí hay un par de razones para tener diferentes nombres de encabezados C vs C++:

  • Formato de código automático, es posible que tenga diferentes pautas para formatear el código C y C++. Si los encabezados están separados por extensión, puede configurar su editor para aplicar el formato apropiado automáticamente
  • Naming, he estado en proyectos donde había bibliotecas escritas en C y luego los wrappers se habían implementado en C++. Dado que los encabezados generalmente tenían nombres similares, es decir, Feature.h vs Característica.hpp, eran fáciles de distinguir.
  • Inclusión, tal vez su proyecto tiene versiones más apropiadas disponibles escritas en C++, pero está utilizando la versión en C (véase el punto anterior). Si los encabezados llevan el nombre del lenguaje en el que se implementan, puede detectar fácilmente todos los encabezados C y comprobar si hay versiones de C++.

Recuerde, C es no C++ y puede ser muy peligroso mezclar y combinar a menos que sepa lo que está haciendo. Nombrar sus fuentes apropiadamente le ayuda distingue los idiomas.

 426
Author: David Holm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-30 11:41:07

Uso .hpp porque quiero que el usuario diferencie qué cabeceras son cabeceras de C++, y qué cabeceras son cabeceras de C.

Esto puede ser importante cuando tu proyecto está usando módulos C y C++: Como alguien explicó antes que yo, debes hacerlo con mucho cuidado, y comienza por el "contrato" que ofreces a través de la extensión

.hpp: C++ Headers

(O .hxx, o .hh, o lo que sea)

Este encabezado es solo para C++.

Si estás en una C module, ni siquiera intentes incluirlo. No te gustará, porque no se hace ningún esfuerzo para hacerlo compatible con C (se perdería demasiado, como sobrecarga de funciones, espacios de nombres, etc. sucesivamente.).

.h: C / C++ compatible o encabezados C puros

Esta cabecera puede ser incluida tanto por una fuente C, como por una fuente C++, directa o indirectamente.

Se puede incluir directamente, estando protegido por la macro __cplusplus:

  • Lo que significa que, desde el punto de vista de C++, el código compatible con C será definido como extern "C".
  • Desde el punto de vista de C, todo el código de C será claramente visible, pero el código de C++ estará oculto (porque no se compilará en un compilador de C).

Por ejemplo:

#ifndef MY_HEADER_H
#define MY_HEADER_H

   #ifdef __cplusplus
      extern "C"
      {
   #endif

   void myCFunction() ;

   #ifdef __cplusplus
      } // extern "C"
   #endif

#endif // MY_HEADER_H

O podría incluirse indirectamente por el correspondiente.encabezado hpp que lo encierra con la declaración extern "C".

Por ejemplo:

#ifndef MY_HEADER_HPP
#define MY_HEADER_HPP

extern "C"
{
#include "my_header.h"
}

#endif // MY_HEADER_HPP

Y:

#ifndef MY_HEADER_H
#define MY_HEADER_H

void myCFunction() ;

#endif // MY_HEADER_H
 188
Author: paercebal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-21 15:52:40

Siempre consideré el encabezado .hpp como una especie de portmanteau de archivos .h y .cpp...un encabezado que también contiene detalles de implementación.

Normalmente cuando he visto (y uso) .hpp como una extensión, no hay un archivo .cpp correspondiente. Como otros han dicho, esta no es una regla dura y rápida, solo cómo tiendo a usar archivos .hpp.

 37
Author: Perculator,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-18 09:22:37

No importa qué extensión utilice. Cualquiera está bien.

Utilizo *.h para C y *.hpp para C++.

 20
Author: Burkhard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-18 09:07:49

EDITAR [Sugerencia añadida de Dan Nissenbaum]:

Por una convención .los archivos hpp se utilizan cuando los prototipos se definen en la propia cabecera. Tales definiciones en encabezados son útiles en el caso de plantillas, ya que el compilador genera el código para cada tipo solo en la instanciación de plantillas. Por lo tanto, si no están definidos en los archivos de encabezado, sus definiciones no se resolverán en el momento del enlace desde otras unidades de compilación. Si su proyecto es un proyecto solo de C++ que hace pesado uso de plantillas, esta convención podría ser útil.

Ciertas bibliotecas de plantillas que se adhieren a esta convención proporcionan encabezados con .extensiones hpp para indicar que no tienen correspondiente .archivos cpp.

Algunas otras bibliotecas de plantillas usan otra convención, como usar .h para las cabeceras de C y .hpp para C++; un buen ejemplo sería la biblioteca boost.

Cita de Boost FAQ,

Las extensiones de archivo comunican el" tipo " del archivo, tanto a los humanos y a los programas de ordenador. El '.la extensión h ' se utiliza para el encabezado C archivos, y por lo tanto comunica lo incorrecto sobre el encabezado C++ file. El uso de ninguna extensión no comunica nada y obliga a la inspección del contenido del archivo para determinar el tipo. Utilizar '.hpp ' sin ambigüedades lo identifica como archivo de encabezado C++, y funciona bien en la práctica real. (Rainer Deyke)

 19
Author: ProgramCpp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-29 20:49:26

Recientemente he comenzado a usar *.hpp para encabezados de c++.

La razón es que uso emacs como mi editor principal y entra automáticamente en modo c cuando se carga un archivo *.h y en modo c++cuando se carga un archivo *.hpp.

Aparte de ese hecho no veo buenas razones para elegir *.h sobre *.hpp o viceversa.

 9
Author: Serge,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-18 09:22:56

En uno de mis trabajos a principios de los 90, usamos .cc y .hh para los archivos fuente y encabezado respectivamente. Todavía lo prefiero sobre todas las alternativas, probablemente porque es más fácil de escribir.

 5
Author: camh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-30 11:15:49

Prefiero .hpp para C++ para dejar claro tanto a los editores como a otros programadores que es un encabezado de C++ en lugar de un archivo de encabezado de C.

 5
Author: JohnMcG,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-30 14:15:28

Puedes llamar a tu incluye lo que quieras.

Solo necesita especificar ese nombre completo en el #include.

Sugiero que si trabajas con C para usar .h y cuando trabajas con C++ para usar .hpp.

Al final es solo una convención.

 5
Author: slashmais,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-18 09:22:53

C++ ("C Plus Plus") tiene sentido .cpp

Tener archivos de cabecera con a .la extensión hpp no tiene el mismo flujo lógico.

 4
Author: Dynite,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-30 15:18:51

Estoy respondiendo esto como un recordatorio, para dar punto a mi comentario(s) sobre "user1949346" respuesta a esta misma OP.


Así que como muchos ya respondieron: de cualquier manera está bien. Seguido de énfasis de sus propias impresiones.

Introductivo, como también en los comentarios privados mencionados, mi opinión es C++ se propone que las extensiones de encabezado sean .h si no hay realmente ninguna razón en contra.

Dado que los documentos ISO / IEC utilizan esta notación de archivos de encabezado y no la coincidencia de cadena con .hpp incluso ocurre en sus documentaciones de lenguaje sobre C++.

Pero ahora estoy apuntando a una razón aprobable POR QUÉ eitherway está bien, y especialmente por qué no es sujeto del lenguaje que sí mismo.

Así que aquí vamos.

La documentación C++ (en realidad estoy tomando referencia de la versión N3690) define un encabezado tiene que ser conforme a la siguiente sintaxis:

2.9 Nombres de encabezado

header-name:
    < h-char-sequence >
    " q-char-sequence "
h-char-sequence:
    h-char
    h-char-sequence h-char
h-char:
    any member of the source character set except new-line and >
q-char-sequence:
    q-char
    q-char-sequence q-char
q-char:
    any member of the source character set except new-line and "

Para que podamos extraer de esta parte es el nombre de hearfile puede ser cualquier cosa que sea válida en el código fuente, también. Excepto que contenga '\n' caracteres y dependiendo de si debe ser incluido por <> no está permitido contener un >. O de otra manera si está incluido por ""-include no está permitido contener un ".

En otras palabras: si tuvieras un entorno soportando filenamse como prettyStupidIdea.>, un include como:

#include "prettyStupidIdea.>"

Sería válido, pero:

#include <prettyStupidIdea.>>

No sería válido. El otro camino más o menos igual.

Como ya explica el propio nombre del archivo, incluso esto se ajustaría a C++, sería una idea bastante estúpida.

Y por eso .hpp también es válido.

¡Pero no un resultado del comité que diseñó el lenguaje!

Así que discutir sobre usar .hpp es lo mismo que hacerlo sobre .cc, .mm o lo que sea que lea en otros posts sobre este tema.

Tengo que admitir que no tengo ni idea de dónde vino .hpp, pero apostaría una inventor de alguna herramienta de análisis, IDE u otra cosa relacionada con C++ llegó a esta idea para optimizar algunos procesos internos o simplemente para inventar algunas (probablemente incluso necesarias) nuevas convenciones de nombres.

Pero no es parte del lenguaje.

Y cada vez que uno decide usarlo de esta manera. Puede ser porque le gusta más o porque algunas aplicaciones del flujo de trabajo lo requieren, nunca1 es un requisito del idioma. Así que ¿quién dice "el pp es porque se utiliza con C++", simplemente está mal.

C++ permite cualquier cosa que respete el párrafo anterior. Y si hay algo que el comité propuso usar, entonces está usando .h ya que esta es la extensión demandada en todos los ejemplos del documento ISO.

Conclusión:

Mientras no veas/sientas la necesidad de usar .h sobre .hpp o viceversa, no deberías molestarte. Porque ambos formarían un nombre de encabezado válido de la misma calidad con respecto al estándar. Y por lo tanto, cualquier cosa que REQUIERA que use .h o .hpp es una restricción adicional de la norma que incluso podría estar en contradicción con otras restricciones adicionales que no se ajustan entre sí. Pero como OP no menciona ninguna restricción adicional de idioma, esta es la única respuesta correcta y aprobable a la pregunta

"*.h or *.hpp para sus definiciones de clase " es:

Ambos son igualmente correctos y aplicables mientras no haya restricciones externas están presentes.


1Por supuesto, no puedo decir lo que algunas versiones futuras traerán con él!

 4
Author: dhein,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-08 13:14:45

Afortunadamente, es simple.

Debe usar el .extensión hpp si está trabajando con C++ y debe usar .h para C o mezcla de C y C++.

 4
Author: Nykal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-05 11:51:14

Codegear C++Builder utiliza.hpp para archivos de cabecera generados automáticamente a partir de archivos fuente de Delphi, y .h archivos para sus" propios " archivos de cabecera.

Por lo tanto, cuando estoy escribiendo un archivo de encabezado C++ siempre uso .h.

 3
Author: Roddy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-30 10:53:02

Bjarne Stroustrup y Herb Sutter tienen una declaración a esta pregunta en sus directrices de C++ Core que se encuentran en: https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#S-source que también se refiere a los últimos cambios en la extensión estándar (C++11, C++14, etc.)

SF.1: Use a .sufijo cpp para archivos de código y .h para archivos de interfaz si su Y project no sigue ya otra convención Razón

Es una larga convención. Pero la consistencia es más importante, así que si tu proyecto usa algo más, sigue eso. Nota

Esta convención refleja un patrón de uso común: Las cabeceras se comparten con más frecuencia con C para compilar como C++ y C, que normalmente utiliza .h, y es es más fácil nombrar todos los encabezados .h en lugar de tener diferentes extensiones para solo aquellos encabezados que están destinados a ser compartidos con C. Por otro lado, los archivos de implementación rara vez se comparten con C, por lo que deberían suelen ser distinguida de .archivos c, por lo que normalmente es mejor nombrar a todos los C++ la implementación archiva otra cosa (por ejemplo .cpp).

Los nombres específicos .h y .cpp no son necesarios (solo se recomienda como un por defecto) y otros nombres están en uso generalizado. Los ejemplos son .hh, .C, y .cxx. Use tales nombres de manera equivalente. En este documento, nos referimos a .h y .cpp > como abreviatura de los archivos de cabecera y de implementación, aunque la extensión puede ser diferente.

Su IDE (si usa uno) puede tener fuertes opiniones sobre sufficies.

No soy un gran fan de esta convención porque si está utilizando una biblioteca popular como boost, su consistencia ya está rota y debería usarla mejor .hpp.

 3
Author: ruuns,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-13 08:32:01

Como muchos aquí ya han mencionado, también prefiero usar .hpp para bibliotecas de solo encabezado que utilizan clases/funciones de plantilla. Prefiero usar .h para archivos de cabecera acompañados por .archivos fuente cpp o bibliotecas compartidas o estáticas.

La mayoría de las bibliotecas que desarrollo están basadas en plantillas y, por lo tanto, solo necesitan ser de encabezado, pero al escribir aplicaciones tiendo a separar la declaración de la implementación y termino con .h y .cpp files

 3
Author: Enzo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-18 23:42:42

Uso .h porque eso es lo que usa Microsoft y lo que crea su generador de código. No hay necesidad de ir a contracorriente.

 1
Author: Mark Ransom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-30 14:26:16

Es fácil para las herramientas y los humanos diferenciar algo. Eso es.

En uso convencional (por boost, etc.), .hpp son específicamente cabeceras de C++. Por otro lado, .h es para encabezados que no son solo de C++(principalmente C). Detectar con precisión el idioma del contenido es generalmente difícil ya que hay muchos casos no triviales, por lo que esta diferencia a menudo hace que una herramienta lista para usar sea fácil de escribir. Para los seres humanos, una vez que la convención, también es fácil de recordar y fácil de utilizar.

Sin embargo, me gustaría señalar que la convención en sí no siempre funciona, como se esperaba.

  • No está forzado por la especificación de lenguajes, ni C ni C++. Existen muchos proyectos que no se ajustan a la convención. Una vez que necesite fusionarlos (para mezclarlos), puede ser problemático.
  • .hpp en sí no es la única opción. ¿Por qué no .hh o .hxx? (Aunque de todos modos, por lo general necesita al menos una regla convencional sobre los nombres de archivo y caminos.)

Yo personalmente uso .h y .hpp en mis proyectos de C++. No sigo la convención anterior, porque:

  • Los lenguajes utilizados por cada parte de los proyectos están explícitamente documentados. No hay posibilidad de mezclar C y C++ en el mismo módulo (directorio). Se requiere que cada biblioteca de 3rdparty cumpla con esta regla.
  • También se documentan las especificaciones lingüísticas conformadas y los dialectos lingüísticos permitidos utilizados por los proyectos. (De hecho, incluso documento la fuente de las características estándar y corrección de errores (en el estándar de lenguaje) que se utiliza.) Esto es algo más importante que distinguir los lenguajes usados, ya que es demasiado propenso a errores y el costo de la prueba (por ejemplo, compatibilidad con compiladores) puede ser significativo (complicado y lento), especialmente en un proyecto que ya está en casi puro C++. Los nombres de archivo son demasiado débiles para manejar esto.
  • Incluso para el mismo dialecto de C++, puede haber propiedades más importantes adecuado a la diferencia. Por ejemplo, véase la convención infra.
  • Los nombres de archivo son esencialmente piezas de metadatos frágiles. La violación de la convención no es tan fácil de detectar. Para ser estable en el manejo del contenido, una herramienta eventualmente no solo debe depender de los nombres. La diferencia entre extensiones es solo una pista. Tampoco se debe esperar que las herramientas que lo usan se comporten igual todo el tiempo, por ejemplo, detección de lenguaje de archivos .h en github.com. (Puede haber algo en comentarios como shebang para que estos archivos fuente sean mejores metadatos, pero incluso no es convencional como los nombres de archivo, por lo que tampoco es confiable en general.)

Normalmente uso .hpp en encabezados de C++ y los encabezados deben usarse (mantenerse) de una manera de solo encabezado, por ejemplo, como bibliotecas de plantillas. Para otras cabeceras en .h, o bien hay un archivo .cpp correspondiente como implementación, o es una cabecera no-C++. Este último es trivial para diferenciar a través de los contenidos de la encabezado por humanos (o por herramientas con metadatos incrustados explícitos, si es necesario).

 1
Author: FrankHB,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-30 01:27:36

La extensión del archivo fuente puede tener un significado para su sistema de compilación, por ejemplo, puede tener una regla en su makefile para los archivos .cpp o .c, o su compilador (por ejemplo, Microsoft cl.exe) puede compilar el archivo como C o C++ dependiendo de la extensión.

Debido a que debe proporcionar el nombre de archivo completo a la directiva #include, la extensión del archivo de encabezado es irrelevante. Puede incluir un archivo .c en otro archivo fuente si lo desea, porque es solo una inclusión textual. Su el compilador podría tener una opción para volcar la salida preprocesada que lo aclarará (Microsoft: /P para preprocesar a file, /E para preprocesar a stdout, /EP omitir #line directivas, /C mantener los comentarios)

Puede optar por usar .hpp para archivos que solo son relevantes para el entorno C++, es decir, que usan características que no se compilan en C.

 0
Author: Mike Dimmick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-30 11:34:42

En "The C++ Programming Language, Third Edition by Bjarne Stroustrup", el libro de C++ de lectura obligatoria nº1, utiliza *.h. Así que asumo que la mejor práctica es usar *.h.

Sin embargo, *.¡hpp también está bien!

 0
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-29 16:25:41

No hay ninguna ventaja para ninguna extensión en particular, aparte de que una puede tener un significado diferente para usted, el compilador y/o sus herramientas. header.h es una cabecera válida. header.hpp es una cabecera válida. header.hh es una cabecera válida. header.hx es una cabecera válida. h.header es una cabecera válida. this.is.not.a.valid.header es un encabezado válido en negación. ihjkflajfajfklaf es una cabecera válida. Siempre y cuando el nombre pueda ser analizado correctamente por el compilador, y el sistema de archivos lo soporte, es un encabezado válido, y la única ventaja de su extensión es lo que se lee en él.

Dicho esto, ser capaz de hacer suposiciones con precisión basadas en la extensión es muy útil, por lo que sería prudente usar un conjunto de reglas fácilmente comprensibles para sus archivos de encabezado. Personalmente, prefiero hacer algo como esto:

  1. Si ya hay directrices establecidas, sígalas para evitar confusiones.
  2. Si todos los archivos fuente del proyecto son para el mismo lenguaje, use .h. No hay ambigüedad.
  3. Si algunos encabezados son compatibles con varios idiomas, mientras que otros solo son compatibles con un solo idioma, las extensiones se basan en el lenguaje más restrictivo con el que un encabezado es compatible. Un encabezado compatible con C, o con ambos C & C++, obtiene .h, mientras que un encabezado compatible con C++ pero no C obtiene .hpp o .hh o algo por el estilo.

Esto, por supuesto, es solo una de muchas formas de manejar extensiones, y no necesariamente puede confía en tu primera impresión incluso si las cosas parecen sencillas. Por ejemplo, he visto mención de usar .h para encabezados normales, y .tpp para encabezados que solo contienen definiciones para funciones miembro de clase con plantilla, con archivos .h que definen clases con plantilla incluyendo los archivos .tpp que definen sus funciones miembro (en lugar de la cabecera .h que contiene directamente tanto la declaración de función como la definición). Por otro ejemplo, un buen número de personas siempre reflejan la el lenguaje del encabezado en su extensión, incluso cuando no hay posibilidad de ambigüedad; para ellos, .h es siempre un encabezado C y .hpp (o .hh, o .hxx, etc.) es siempre una cabecera C++. Y una vez más, algunas personas usan .h para "encabezado asociado con un archivo de origen" y .hpp para "encabezado con todas las funciones definidas en línea".

Teniendo en cuenta esto, la principal ventaja vendría en nombrar consistentemente sus encabezados en el mismo estilo, y hacer que ese estilo sea fácilmente evidente para cualquiera que examine su codificar. De esta manera, cualquier persona familiarizada con su estilo de codificación habitual será capaz de determinar lo que quiere decir con cualquier extensión dada con solo un vistazo superficial.

 0
Author: Justin Time,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-15 03:50:46