Primero, para abordar su primera consulta:
Cuando vea esto en el archivo .h :
#ifndef FILE_H
#define FILE_H
/* ... Declarations etc here ... */
#endif
Esta es una técnica de preprocesador para evitar que un archivo de encabezado se incluya varias veces, lo que puede ser problemático por varias razones. Durante la compilación de su proyecto, cada archivo .cpp (generalmente) se compila. En términos simples, esto significa que el compilador tomará su archivo .cpp , abrirá todos los archivos #included, los concatenará en un solo archivo de texto masivo y luego realizará un análisis de sintaxis y finalmente lo convertirá en algún código intermedio, optimizará / realizará otro tareas, y finalmente generar la salida del ensamblaje para la arquitectura de destino. Debido a esto, si un archivo está #includedvarias veces bajo un .cpparchivo, el compilador agregará su contenido de archivo dos veces, por lo que si hay definiciones dentro de ese archivo, recibirá un error del compilador que le indica que redefinió una variable. Cuando el archivo es procesado por el paso del preprocesador en el proceso de compilación, la primera vez que se alcanza su contenido, las dos primeras líneas verificarán siFILE_H se ha definido para el preprocesador. De lo contrario, definirá FILE_Hy continuará procesando el código entre este y la #endifdirectiva. La próxima vez que el preprocesador vea el contenido de ese archivo, la verificación contra FILE_Hserá falsa, por lo que se escaneará inmediatamente #endify continuará después. Esto evita errores de redefinición.
Y para abordar su segunda preocupación:
En la programación en C ++ como práctica general, separamos el desarrollo en dos tipos de archivos. Uno es con una extensión de .h y lo llamamos un "archivo de encabezado". Por lo general, proporcionan una declaración de funciones, clases, estructuras, variables globales, typedefs, preprocesamiento de macros y definiciones, etc. Básicamente, solo le brindan información sobre su código. Luego tenemos la extensión .cpp que llamamos un "archivo de código". Esto proporcionará definiciones para esas funciones, miembros de clase, cualquier miembro de estructura que necesite definiciones, variables globales, etc. Por lo tanto, el archivo .h declara el código, y el archivo .cpp implementa esa declaración. Por esta razón, generalmente durante la compilación compilamos cada .cpparchivo en un objeto y luego vincular esos objetos (porque casi nunca ve un archivo .cpp incluye otro archivo .cpp ).
Cómo se resuelven estos elementos externos es un trabajo para el vinculador. Cuando su compilador procesa main.cpp , obtiene declaraciones para el código en class.cpp al incluir class.h . Solo necesita saber cómo se ven estas funciones o variables (que es lo que le da una declaración). Por lo tanto, compila su archivo main.cpp en algún archivo de objeto ( llámelo main.obj ). Del mismo modo, class.cpp se compila en un class.objexpediente. Para producir el ejecutable final, se invoca un vinculador para vincular esos dos archivos de objetos. Para cualquier variable o función externa no resuelta, el compilador colocará un código auxiliar donde ocurre el acceso. El enlazador luego tomará este código auxiliar y buscará el código o la variable en otro archivo de objeto listado, y si se encuentra, combina el código de los dos archivos de objeto en un archivo de salida y reemplaza el código auxiliar con la ubicación final de la función o variable. De esta manera, su código en main.cpp puede invocar funciones y usar variables en class.cpp SI Y SOLO SI SE DECLARAN EN class.h .
Espero que esto haya sido útil.