*.h o *.hpp para sus definiciones de clase
Siempre he usado un *.h
archivo para las definiciones de mis clases, pero después de leer el código de la biblioteca Boost, me di cuenta de que todos usan *.hpp
. Siempre he tenido 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
over *.h
?
Aquí hay un par de razones para tener nombres diferentes para los encabezados de C y C++:
- Formateo automático de código, es posible que tenga pautas diferentes para formatear código C y C++. Si los encabezados están separados por extensión, puede configurar su editor para que aplique el formato apropiado automáticamente
- En cuanto a los nombres, he estado en proyectos en los que había bibliotecas escritas en C y luego se implementaron contenedores en C++. Dado que los encabezados generalmente tenían nombres similares, es decir, Feature.h vs Feature.hpp, eran fáciles de distinguir.
- Inclusión, tal vez su proyecto tenga versiones más apropiadas disponibles escritas en C++ pero esté usando la versión C (ver punto anterior). Si los encabezados llevan el nombre del lenguaje en el que están implementados, puede detectar fácilmente todos los encabezados C y buscar versiones de C++.
Recuerde, C no es C++ y puede ser muy peligroso mezclarlo y combinarlo a menos que sepa lo que está haciendo. Nombrar tus fuentes apropiadamente te ayuda a diferenciar los idiomas.
Utilizo .hpp porque quiero que el usuario diferencie qué encabezados son encabezados C++ y qué encabezados son encabezados C.
Esto puede ser importante cuando su proyecto utiliza módulos C y C++: como alguien más me explicó antes, debe hacerlo con mucho cuidado y comienza con el "contrato" que ofrece a través de la extensión.
.hpp: encabezados C++
(O .hxx, o .hh, o lo que sea)
Este encabezado es solo para C++.
Si estás en un módulo C, ni siquiera intentes incluirlo. No le gustará, porque no se hace ningún esfuerzo para hacerlo compatible con C (se perderían demasiadas cosas, como sobrecarga de funciones, espacios de nombres, etc., etc.).
.h: compatible con C/C++ o encabezados C puros
Este encabezado puede ser incluido tanto por una fuente C como por una fuente C++, directa o indirectamente.
Se puede incluir directamente, estando protegido por la __cplusplus
macro:
- Lo que significa que, desde el punto de vista de C++, el código compatible con C se definirá como
extern "C"
. - Desde el punto de vista de C, todo el código C será claramente visible, pero el código 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 mediante el encabezado .hpp correspondiente que lo incluye junto con la extern "C"
declaración.
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
Siempre consideré que el .hpp
encabezado era una especie de maleta de archivos .h
y .cpp
... un encabezado que también contiene detalles de implementación.
Normalmente, cuando lo he visto (y usado) .hpp
como extensión, no hay ningún .cpp
archivo correspondiente. Como han dicho otros, esta no es una regla estricta, sino simplemente la forma en que tiendo a usar .hpp
los archivos.