Tout d'abord, pour répondre à votre première demande:
Lorsque vous voyez cela dans le fichier .h :
#ifndef FILE_H
#define FILE_H
/* ... Declarations etc here ... */
#endif
Il s'agit d'une technique de préprocesseur pour empêcher un fichier d'en-tête d'être inclus plusieurs fois, ce qui peut être problématique pour diverses raisons. Lors de la compilation de votre projet, chaque fichier .cpp (généralement) est compilé. En termes simples, cela signifie que le compilateur prendra votre fichier, le compilateur ajoutera deux fois le contenu de son fichier, donc s'il y a des définitions dans ce fichier, vous obtiendrez une erreur du compilateur vous indiquant que vous avez redéfini une variable. Lorsque le fichier est traité par l'étape du préprocesseur dans le processus de compilation, la première fois que son contenu est atteint, les deux premières lignes vérifieront s'il a été défini pour le préprocesseur. Sinon, il définira et continuera à traiter le code entre lui et le fichier .cpp , ouvrira tous les fichiers #included, les concaténera tous dans un fichier texte massif, puis effectuera une analyse de syntaxe et enfin il le convertira en un code intermédiaire, optimisera / exécutera d'autres tâches, et enfin générer la sortie d'assembly pour l'architecture cible. Pour cette raison, si un fichier est #includedplusieurs fois sous un .cppFILE_HFILE_H#endifdirectif. La prochaine fois que le contenu de ce fichier sera vu par le préprocesseur, la vérificationFILE_H sera fausse, de sorte qu'il analysera immédiatement le#endif et continuera après lui. Cela évite les erreurs de redéfinition.
Et pour répondre à votre deuxième préoccupation:
Dans la programmation C ++ en tant que pratique générale, nous séparons le développement en deux types de fichiers. L'un est avec une extension de .h et nous l'appelons un "fichier d'en-tête". Ils fournissent généralement une déclaration de fonctions, de classes, de structures, de variables globales, de typedefs, de macros de prétraitement et de définitions, etc. Fondamentalement, ils vous fournissent simplement des informations sur votre code. Ensuite, nous avons l' extension .cpp que nous appelons un "fichier de code". Cela fournira des définitions pour ces fonctions, les membres de classe, tous les membres de structure qui ont besoin de définitions, de variables globales, etc. Ainsi, le fichier .h déclare le code et le fichier .cpp implémente cette déclaration. Pour cette raison, nous compilons généralement chaque .cpp lors de la compilationdans un objet, puis liez ces objets (car vous ne voyez presque jamais un fichier .cpp inclure un autre fichier .cpp ).
La façon dont ces externes sont résolus est un travail pour l'éditeur de liens. Lorsque votre compilateur traite main.cpp , il obtient des déclarations pour le code de class.cpp en incluant class.h . Il a seulement besoin de savoir à quoi ressemblent ces fonctions ou variables (ce que vous donne une déclaration). Il compile donc votre fichier main.cpp dans un fichier objet (appelez-le main.obj ). De même, class.cpp est compilé dans un class.objfichier. Pour produire l'exécutable final, un éditeur de liens est appelé pour lier ces deux fichiers objets ensemble. Pour toutes les variables ou fonctions externes non résolues, le compilateur placera un stub où l'accès se produit. L'éditeur de liens prendra alors ce stub et recherchera le code ou la variable dans un autre fichier objet répertorié, et s'il est trouvé, il combine le code des deux fichiers objet dans un fichier de sortie et remplace le stub par l'emplacement final de la fonction ou variable. De cette façon, votre code dans main.cpp peut appeler des fonctions et utiliser des variables dans class.cpp SI ET UNIQUEMENT SI ILS SONT DÉCLARÉS DANS class.h .
J'espère que cela a été utile.