Um Ihre erste Anfrage zu beantworten:
Wenn Sie dies in der .h- Datei sehen:
#ifndef FILE_H
#define FILE_H
/* ... Declarations etc here ... */
#endif
Dies ist eine Präprozessortechnik, mit der verhindert wird, dass eine Headerdatei mehrmals enthalten ist, was aus verschiedenen Gründen problematisch sein kann. Während der Kompilierung Ihres Projekts wird (normalerweise) jede CPP- Datei kompiliert. In einfachen Worten bedeutet dies, dass der Compiler Ihre CPP- Datei nimmt, alle Dateien #includeddamit öffnet , sie alle zu einer massiven Textdatei verkettet, dann eine Syntaxanalyse durchführt und sie schließlich in einen Zwischencode konvertiert, andere optimiert / ausführt Aufgaben und generieren schließlich die Assembly-Ausgabe für die Zielarchitektur. Aus diesem Grund, wenn sich eine Datei #includedmehrmals unter einer CPP befindetDatei, der Compiler hängt seinen Dateiinhalt zweimal an. Wenn also Definitionen in dieser Datei vorhanden sind, wird ein Compilerfehler angezeigt, der Sie darüber informiert, dass Sie eine Variable neu definiert haben. Wenn die Datei vom Präprozessorschritt im Kompilierungsprozess verarbeitet wird, prüfen die ersten beiden Zeilen beim ersten Erreichen ihres Inhalts, ob FILE_Hsie für den Präprozessor definiert wurde. Wenn nicht, wird FILE_Hder Code zwischen ihm und der #endifDirektive definiert und weiter verarbeitet . Wenn der Inhalt dieser Datei das nächste Mal vom Präprozessor angezeigt wird, ist die Prüfung gegen FILE_Hfalsch, sodass sofort nach unten gescannt #endifund danach fortgefahren wird. Dies verhindert Neudefinitionsfehler.
Und um Ihr zweites Anliegen anzusprechen:
In der C ++ - Programmierung als allgemeine Praxis trennen wir die Entwicklung in zwei Dateitypen. Eine ist mit einer Erweiterung von .h und wir nennen dies eine "Header-Datei". Sie enthalten normalerweise eine Deklaration von Funktionen, Klassen, Strukturen, globalen Variablen, Typedefs, Vorverarbeitungsmakros und Definitionen usw. Grundsätzlich liefern sie nur Informationen zu Ihrem Code. Dann haben wir die Erweiterung .cpp, die wir als " Codedatei " bezeichnen. Dadurch werden Definitionen für diese Funktionen, Klassenmitglieder und alle Strukturelemente bereitgestellt , die Definitionen, globale Variablen usw. benötigen. Die .h- Datei deklariert also Code, und die .cpp- Datei implementiert diese Deklaration. Aus diesem Grund kompilieren wir in der Regel während der Kompilierung jede .cppDatei in ein Objekt und verknüpfen Sie diese Objekte (da Sie fast nie sehen, dass eine CPP- Datei eine andere CPP- Datei enthält).
Wie diese externen Elemente aufgelöst werden, ist eine Aufgabe für den Linker. Wenn Ihr Compiler verarbeitet main.cpp , wird es Erklärungen für den Code in class.cpp , indem class.h . Es muss nur wissen, wie diese Funktionen oder Variablen aussehen (was eine Deklaration Ihnen gibt). So kompiliert es Ihre main.cpp- Datei in eine Objektdatei (nennen Sie es main.obj ). In ähnlicher Weise wird class.cpp in eine class.obj kompiliertDatei. Um die endgültige ausführbare Datei zu erstellen, wird ein Linker aufgerufen, um diese beiden Objektdateien miteinander zu verknüpfen. Für nicht aufgelöste externe Variablen oder Funktionen platziert der Compiler einen Stub, an dem der Zugriff erfolgt. Der Linker nimmt dann diesen Stub und sucht nach dem Code oder der Variablen in einer anderen aufgelisteten Objektdatei. Wenn er gefunden wird, kombiniert er den Code aus den beiden Objektdateien zu einer Ausgabedatei und ersetzt den Stub durch den endgültigen Speicherort der Funktion oder Variable. Auf diese Weise kann Ihr Code in main.cpp Funktionen aufrufen und Variablen in class.cpp verwenden, WENN UND NUR, WENN SIE IN class.h ERKLÄRT SIND .
Ich hoffe das war hilfreich.