Beim Schreiben von Projekten in C ++ ist das Dateisegmentierungsmanagement sehr erforderlich. Heute bringt Ihnen der Herausgeber von Foxin Technology Channel eine detaillierte Erklärung der Header -Dateien und Quelldateien in C ++. Ich hoffe, es wird für Sie hilfreich sein, dieses Wissen zu lernen!
Detaillierte Erläuterung von Header -Dateien und Quelldateien in C ++
1. C ++ Compilation -Modus
Im Allgemeinen gibt es in einem C ++ - Programm nur zwei Arten von Dateien - .CPP -Datei und .h -Datei. Unter ihnen wird die .CPP -Datei als C ++ - Quelldatei bezeichnet und der Quellcode von C ++ wird darin platziert. Während die .h -Datei als C ++ - Header -Datei bezeichnet wird und der Quellcode von C ++ darin platziert wird.
Die C ++ - Sprache unterstützt "separate Zusammenstellung". Mit anderen Worten, der gesamte Inhalt eines Programms kann in verschiedene Teile unterteilt und in verschiedene .cpp -Dateien platziert werden. Die Dinge in der .cpp -Datei sind relativ unabhängig. Beim Kompilieren (kompilieren) müssen Sie nicht mit anderen Dateien kommunizieren. Sie müssen nur mit anderen Zieldateien verlinken, nachdem Sie sie in die Zieldatei zusammengestellt haben. Beispielsweise ist eine globale Funktion "void a () {}" in der Datei A.CPP definiert, und diese Funktion muss in der Datei B.CPP aufgerufen werden. Trotzdem müssen die Dateien A.CPP und B.CPP die Existenz des anderen nicht kennen, sondern können sie separat kompilieren. Nachdem Sie sie in die Zieldatei zusammengestellt haben, verlinken Sie sie und das gesamte Programm kann ausgeführt werden.
Wie wird das erreicht? Aus der Sicht des Schreibens von Programmen ist es sehr einfach. In der Datei B.CPP deklarieren Sie vor dem Aufruf der Funktion "void a ()" die Funktion "void a ();" Erste. Dies liegt daran, dass der Compiler beim Kompilieren von B.CPP eine Symboltabelle erzeugt. Symbole wie "void a ()", die nicht gesehen werden können, werden in dieser Tabelle gespeichert. Wenn der Compiler erneut verlinkt wird, sucht er nach der Definition dieses Symbols in anderen Objektdateien. Sobald das Programm gefunden wurde, kann das Programm reibungslos erstellt werden.
Beachten Sie, dass hier zwei Konzepte erwähnt werden, eine "Definition" und der andere "Deklaration". Einfach ausgedrückt, "Definition" bedeutet, ein Symbol vollständig und vollständig zu beschreiben: ob es sich um eine Variable oder eine Funktion handelt, welchen Typ es zurückgibt, welche Parameter es benötigt usw. Ich werde es zuerst benutzen. Wenn Sie verlinken, gehen Sie zu einem anderen Ort, um herauszufinden, was es ist. Beim Definieren müssen Sie ein Symbol (Variable oder Funktion) entsprechend der C ++ - Syntax vollständig definieren, und beim Deklarieren müssen Sie nur den Prototyp dieses Symbols schreiben. Es ist zu beachten, dass ein Symbol im gesamten Programm mehrmals deklariert werden kann, aber nur einmal definiert werden muss. Stellen Sie sich vor, wenn es zwei verschiedene Definitionen eines Symbols gibt, wen sollte der Compiler dann zuhören?
Dieser Mechanismus bringt C ++ - Programmierern viele Vorteile und führt auch zu einer Methode zum Schreiben von Programmen. Bedenken Sie, dass wenn es eine sehr häufig verwendete Funktion "void f () {}" gibt, die in vielen .cpp -Dateien im gesamten Programm aufgerufen wird, müssen wir diese Funktion nur in einer Datei definieren und diese Funktion in anderen Dateien deklarieren. Eine Funktion ist leicht zu handhaben und bedeutet nur einen Satz, um ihn zu deklarieren. Was ist jedoch, wenn es zu viele Funktionen gibt, wie z. B. ein paar mathematische Funktionen, Hunderte von ihnen? Kann jeder Programmierer sicher sein, alle Funktionen genau aufzuschreiben und aufzuschreiben?
2. Was ist eine Header -Datei?
Offensichtlich ist die Antwort unmöglich. Es gibt jedoch eine sehr einfache Möglichkeit, den Programmierern zu helfen, sich die Mühe zu bewahren, so viele Funktionsprototypen zu erinnern: Wir können zuerst alle Deklarationsanweisungen von Hunderten von Funktionen schreiben und in eine Datei einfügen. Wenn der Programmierer sie braucht, kopieren Sie all diese Dinge in seinen Quellcode.
Diese Methode ist sicherlich machbar, aber sie ist immer noch zu problematisch und scheint ungeschickt zu sein. Die Header -Datei kann also ihre Rolle spielen. Die sogenannte Header-Datei hat tatsächlich den gleichen Inhalt wie der Inhalt in der .cpp-Datei, die beide C ++-Quellcode sind. Die Header -Datei muss jedoch nicht kompiliert werden. Wir geben alle Funktionserklärungen in eine Header -Datei ein. Wenn eine .cpp -Quelldatei sie benötigt, können sie in dieser .cpp -Datei über einen Makro -Befehl "#include" aufgenommen werden, sodass ihre Inhalte in die .cpp -Datei zusammengefasst werden. Wenn die .CPP -Datei zusammengestellt wird, werden die Funktionen dieser enthaltenen .H -Dateien abgespielt.
Lassen Sie uns ein Beispiel geben. Angenommen, alle mathematischen Funktionen haben nur zwei: F1 und F2, dann setzen wir ihre Definitionen in Math.cpp ein:
/ * math.cpp */double f1 () {// Mach hier etwas ... return;} double f2 (double a) {// Mach hier etwas ... return a * a;}/ * Ende von Math.cpp */Und legen Sie die Erklärung der "diese" Funktionen in eine Header -Datei Math.h:
/ * math.h */double f1 (); double f2 (double);/ * Ende von Math.h *//
In einer anderen Datei main.cpp möchte ich diese beiden Funktionen aufrufen, daher muss ich nur die Header -Datei einfügen:
/ * main.cpp */#include "math.h" main () {int nummer1 = f1 (); int nummer2 = f2 (number1);}/ * Ende von main.cpp */Dies ist ein vollständiges Programm. Es ist zu beachten, dass die .H -Datei nicht nach dem Befehl des Compilers geschrieben werden muss, sondern muss an der Stelle gefunden werden, an der der Compiler sie finden kann (z. B. im selben Verzeichnis wie main.cpp). Main.cpp und Math.cpp können zusammengestellt werden, um Main.O bzw. Math.o zu generieren und diese beiden Objektdateien dann zu verknüpfen, und das Programm kann ausgeführt werden.
3. #include
#include ist ein Makrobefehl aus der C -Sprache, der vor dem Zusammenschluss des Compilers funktioniert, wenn er vorkompiliert ist. Der Zweck von #include besteht darin, den Inhalt der danach geschriebenen Datei vollständig in die aktuelle Datei einzubeziehen. Es ist erwähnenswert, dass es keine anderen Funktionen oder Unterfunktionen hat. Seine Funktion besteht darin, jeden Ort zu ersetzen, den es mit dem Inhalt der Datei, die sie dahinter schreibt, erscheint. Einfacher Textersatz, sonst nichts. Daher wird der erste Satz in der Main.CPP -Datei (#include "math.h") vor der Zusammenstellung durch den Inhalt der math.h -Datei ersetzt. Das heißt, wenn der Zusammenstellungsprozess beginnen, hat sich der Inhalt von Main.cpp geändert:
/ * ~ main.cpp */double f1 (); double f2 (double); main () {int nummer1 = f1 (); int nummer2 = f2 (Nummer1);}/ * Ende von ~ main.cpp */Nicht mehr oder weniger, genau richtig. Wenn wir zusätzlich zu Main.cpp zusätzlich zu Main.cpp F1- und F2 -Funktionen verwenden, müssen wir nur einen Satz #include "math.h" schreiben, bevor wir diese beiden Funktionen verwenden.
4. Was sollte in der Header -Datei geschrieben werden
Durch die obige Diskussion können wir verstehen, dass die Funktion der Header -Datei in andere .CPPs aufgenommen werden soll. Sie selbst nehmen nicht an der Zusammenstellung teil, aber tatsächlich werden ihre Inhalte in mehreren .cpp -Dateien zusammengestellt. Durch die Regel der Definition können wir leicht zu dem Schluss kommen, dass nur Variablen und Funktionen in der Header -Datei platziert werden sollten und ihre Definitionen nicht platziert werden sollten. Da der Inhalt einer Header -Datei tatsächlich in mehrere verschiedene .CPP -Dateien eingeführt wird und alle zusammengestellt werden. Es ist natürlich in Ordnung, eine Erklärung abzulegen. Wenn Sie eine Definition einlegen, entspricht sie einer Definition eines Symbols (Variable oder Funktion), das in mehreren Dateien angezeigt wird. Obwohl diese Definitionen gleich sind, ist es für den Compiler nicht legal, dies zu tun.
Eine Sache, an die Sie sich erinnern sollten, ist, dass es in der .H -Header -Datei nur Variablen oder Funktionen Definitionen geben kann und keine Definitionen platzieren. Das heißt, Sätze wie: extern int a; und void f (); kann nur in der Header -Datei geschrieben werden. Dies sind die Aussagen. Wenn Sie einen Satz wie int a schreiben; oder void f () {}, sobald die Header -Datei in zwei oder mehr .CPP -Dateien enthalten ist, meldet der Compiler sofort einen Fehler. (Über extern wurde es bereits diskutiert, und der Unterschied zwischen Definition und Erklärung wird hier nicht erörtert.) Es gibt jedoch drei Ausnahmen von dieser Regel.
1. Die Definition des Const -Objekts kann in die Header -Datei geschrieben werden. Da das globale Const -Objekt standardmäßig nicht von Extern deklariert wird, ist es nur in der aktuellen Datei gültig. Schreiben Sie ein solches Objekt in eine Header -Datei, auch wenn es in mehreren anderen .CPP -Dateien enthalten ist, ist das Objekt nur in der Datei mit dieser enthalten und für andere Dateien unsichtbar, sodass es nicht zu mehreren Definitionen führt. Gleichzeitig stellt die Werte der CONT -Objekte in diesen .CPP -Dateien gleichzeitig sicher, dass die Werte der CONT -Objekte in diesen .CPP -Dateien gleich sind, da die Werte der CONT -Objekte in diesen .CPP -Dateien gleich sind, um zwei Vögel mit einem Stein zu töten. In ähnlicher Weise kann die Definition des statischen Objekts auch in die Header -Datei eingefügt werden.
2. Die Definition von Inline -Funktionen kann in die Header -Datei geschrieben werden. Da die Inline -Funktion den Compiler erfordert, dass in der Definition, in der sie sie begegnet, und nicht nur eine gewöhnliche Funktion, die zuerst deklariert und dann verknüpft werden kann (Inline -Funktionen werden nicht verknüpft), muss der Compiler die vollständige Definition der Inline -Funktion während der Kompilierung sehen. Wenn eine Inline -Funktion nur einmal wie eine normale Funktion definiert werden kann, ist dies schwierig. Da es in einer Datei in Ordnung ist, kann ich die Definition der Inline -Funktion am Anfang schreiben, damit ich die Definition sehen kann, wenn ich sie später verwende. Aber was ist, wenn ich diese Funktion in anderen Dateien verwende? Es gibt fast keine gute Lösung dafür, so dass C ++ festlegt, dass Inline -Funktionen im Programm mehrmals definiert werden können. Solange die Inline -Funktion nur einmal in einer .cpp -Datei und in allen .cpp -Dateien erscheint, ist die Definition dieser Inline -Funktion gleich und kann zusammengestellt werden. Offensichtlich ist es sehr ratsam, die Definition von Inline -Funktionen in eine Header -Datei einzubeziehen.
3. Die Definition der Klasse kann in die Header -Datei geschrieben werden. Denn beim Erstellen eines Klassenobjekts in einem Programm kann der Compiler nur wissen, wie das Objekt dieser Klasse angelegt werden sollte, wenn die Definition dieser Klasse vollständig sichtbar ist. Die Anforderungen für die Definition einer Klasse sind im Grunde genommen die gleichen wie die Inline -Funktionen. Daher ist es eine gute Praxis, die Klassendefinition in die Header -Datei einzulegen und die Header -Datei in die in dieser Klasse verwendete .cpp -Datei einzubeziehen. Hier ist erwähnenswert, dass die Definition einer Klasse Datenmitglieder und Funktionsmitglieder enthält. Datenmitglieder werden erst definiert, wenn das spezifische Objekt erstellt wurde (zugewiesener Raum). Funktionsmitglieder müssen jedoch von Anfang an definiert werden, was wir normalerweise als Implementierung der Klasse bezeichnen. Im Allgemeinen besteht unser Ansatz darin, die Klassendefinition in die Header -Datei zu platzieren und den Implementierungscode des Funktionsmitglieds in eine .cpp -Datei zu setzen. Das ist in Ordnung und ein guter Weg. Es gibt jedoch einen anderen Weg. Das heißt, den Implementierungscode der Funktionsmitglieder direkt in die Klassendefinition zu schreiben. In C ++ - Klassen wird der Compiler die Funktion als Inline angesehen, wenn Funktionsmitglieder in der Klassendefinitionsbehörde definiert werden. Daher ist es legal, die Definition von Funktionsmitgliedern in die Klassendefinitionsbehörde zu schreiben und sie in die Header -Datei zusammenzusetzen. Beachten Sie, dass es illegal ist, die Definition des Funktionsmitglieds in die Header -Datei der Klassendefinition und nicht in die Klassendefinition zu schreiben, da das Funktionsmitglied derzeit nicht inline ist. Sobald die Header -Datei in zwei oder mehr .CPP -Dateien enthalten ist, ist dieses Funktionsmitglied neu definiert.
5. Schutzmaßnahmen in Header -Dateien
Beachten Sie, dass wenn die Header -Datei nur Deklarationsanweisungen enthält, es in Ordnung ist, wenn sie in derselben .CPP -Datei ein Vielfaches enthalten ist - da das Auftreten von Deklarationsanweisungen uneingeschränkt ist. Die drei oben diskutierten Headerdateien sind jedoch auch eine sehr häufige Verwendung von Header -Dateien. Sobald eine der drei oben genannten Ausnahmen in einer Header -Datei angezeigt wird und mehrfach von einem .cpp enthalten ist, ist das Problem groß. Denn obwohl die Syntaxelemente in diesen drei Ausnahmen "in mehreren Quelldateien definiert werden können", "können nur einmal in einer Quelldatei angezeigt werden". Stellen Sie sich vor, AH enthält die Definition von Klasse A und BH die Definition von Klasse B. Da die Definition der Klasse B von der Klasse A abhängt, ist AH auch in BH #Included. Jetzt gibt es eine Quelldatei, die sowohl Klasse A als auch Klasse B verwendet, sodass der Programmierer sowohl AH als auch BH in dieser Quelldatei enthält. Zu diesem Zeitpunkt tritt das Problem auf: Die Definition von Klasse A erscheint zweimal in dieser Quelldatei! Das gesamte Programm kann also nicht kompiliert werden. Sie könnten denken, es war ein Programm eines Programmierers - er sollte wissen, dass BH AH enthält - aber tatsächlich sollte er es nicht.
Die Verwendung von "#define" mit bedingter Zusammenstellung kann dieses Problem gut lösen. In einer Header -Datei wird ein Name über #Define definiert, und #ifndef ... #endif ist bedingt kompiliert, damit der Compiler entscheiden kann, ob der nachfolgende Inhalt weiterhin im Header kompiliert werden soll, basierend darauf, ob der Name definiert ist. Obwohl diese Methode einfach ist, müssen Sie sich daran erinnern, sie beim Schreiben der Header -Datei einzuschreiben.
Vielen Dank für das Lesen dieses Artikels. Ich hoffe, die detaillierte Erläuterung der Header -Dateien und Quelldateien in C ++ kann Ihnen helfen. Vielen Dank für Ihre Unterstützung durch das neue Technologiekanal -Netzwerk!