Buscar..


Observaciones

En C ++, como en C, el compilador de C ++ y el proceso de compilación hacen uso del preprocesador de C. Según lo especificado en el manual del preprocesador GNU C, un archivo de encabezado se define de la siguiente manera:

Un archivo de encabezado es un archivo que contiene declaraciones C y definiciones de macro (consulte Macros) que se compartirán entre varios archivos de origen. Solicita el uso de un archivo de encabezado en su programa incluyéndolo, con la directiva de preprocesamiento de C '#include'.

Los archivos de encabezado tienen dos propósitos.

  • Los archivos de encabezado del sistema declaran las interfaces a partes del sistema operativo. Los incluye en su programa para proporcionar las definiciones y declaraciones que necesita para invocar llamadas de sistema y bibliotecas.
  • Sus propios archivos de encabezado contienen declaraciones de interfaces entre los archivos de origen de su programa. Cada vez que tenga un grupo de declaraciones relacionadas y definiciones de macro, todas o la mayoría de las cuales son necesarias en varios archivos de origen diferentes, es una buena idea crear un archivo de encabezado para ellos.

Sin embargo, para el preprocesador de C en sí, un archivo de encabezado no es diferente de un archivo de origen.

El esquema de organización del archivo de encabezado / fuente es simplemente una convención estándar y fuertemente establecida por varios proyectos de software con el fin de proporcionar separación entre la interfaz y la implementación.

Aunque el propio estándar de C ++ no lo impone formalmente, seguir la convención del archivo fuente / encabezado es altamente recomendable y, en la práctica, ya es casi ubicuo.

Tenga en cuenta que los archivos de encabezado pueden ser reemplazados como una convención de estructura de archivos de proyecto por la próxima característica de los módulos, que aún debe considerarse para su inclusión en un futuro estándar de C ++ en el momento de la escritura (por ejemplo, C ++ 20).

Ejemplo básico

El siguiente ejemplo contendrá un bloque de código que se debe dividir en varios archivos de origen, como se indica en los comentarios de // filename .

Archivos fuente

// my_function.h

/* Note how this header contains only a declaration of a function.
 * Header functions usually do not define implementations for declarations
 * unless code must be further processed at compile time, as in templates.
 */

/* Also, usually header files include preprocessor guards so that every header
 * is never included twice.
 *
 * The guard is implemented by checking if a header-file unique preprocessor
 * token is defined, and only including the header if it hasn't been included
 * once before.
 */
#ifndef MY_FUNCTION_H
#define MY_FUNCTION_H

// global_value and my_function() will be
// recognized as the same constructs if this header is included by different files.
const int global_value = 42;
int my_function();

#endif // MY_FUNCTION_H

// my_function.cpp

/* Note how the corresponding source file for the header includes the interface  
 * defined in the header so that the compiler is aware of what the source file is 
 * implementing.
 *
 * In this case, the source file requires knowledge of the global constant
 * global_value only defined in my_function.h. Without inclusion of the header
 * file, this source file would not compile.
 */
#include "my_function.h" // or #include "my_function.hpp"
int my_function() {
  return global_value; // return 42;
}

Los archivos de encabezado luego se incluyen en otros archivos de origen que desean utilizar la funcionalidad definida por la interfaz del encabezado, pero no requieren conocimiento de su implementación (por lo tanto, reduciendo el acoplamiento de código). El siguiente programa hace uso del encabezado my_function.h como se definió anteriormente:

// main.cpp

#include <iostream>       // A C++ Standard Library header.
#include "my_function.h"  // A personal header

int main(int argc, char** argv) {
  std::cout << my_function() << std::endl;
  return 0;
}

El proceso de compilación

Dado que los archivos de encabezado a menudo forman parte de un flujo de trabajo del proceso de compilación, un proceso de compilación típico que hace uso de la convención de archivo de encabezado / fuente generalmente hará lo siguiente.

Suponiendo que el archivo de encabezado y el archivo de código fuente ya están en el mismo directorio, un programador ejecutaría los siguientes comandos:

g++ -c my_function.cpp       # Compiles the source file my_function.cpp
                             # --> object file my_function.o

g++ main.cpp my_function.o   # Links the object file containing the 
                             # implementation of int my_function()
                             # to the compiled, object version of main.cpp
                             # and then produces the final executable a.out

Alternativamente, si uno desea compilar main.cpp en un archivo de objeto primero, y luego vincular solo los archivos de objeto como el paso final:

g++ -c my_function.cpp
g++ -c main.cpp

g++ main.o my_function.o

Plantillas en archivos de encabezado

Las plantillas requieren la generación de código en tiempo de compilación: una función de plantilla, por ejemplo, se convertirá efectivamente en múltiples funciones distintas una vez que una función de plantilla esté parametrizada por el uso en el código fuente.

Esto significa que la función de plantilla, la función de miembro y las definiciones de clase no pueden delegarse a un archivo de código fuente separado, ya que cualquier código que utilizará cualquier construcción con plantilla requiere conocimiento de su definición para generar generalmente cualquier código derivado.

Por lo tanto, el código de plantilla, si se coloca en encabezados, también debe contener su definición. Un ejemplo de esto es a continuación:

// templated_function.h

template <typename T>
T* null_T_pointer() {
  T* type_point = NULL; // or, alternatively, nullptr instead of NULL
                        // for C++11 or later
  return type_point;
} 


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow