C++
Header-Dateien
Suche…
Bemerkungen
In C ++ verwendet der C ++ - Compiler und -Kompilierungsprozess wie in C den C-Präprozessor. Wie im Handbuch zum GNU C-Präprozessor angegeben, wird eine Header-Datei wie folgt definiert:
Eine Header-Datei ist eine Datei, die C-Deklarationen und Makrodefinitionen (siehe Makros) enthält, die von mehreren Quelldateien gemeinsam genutzt werden. Sie fordern die Verwendung einer Header-Datei in Ihrem Programm an, indem Sie sie mit der C-Vorverarbeitungs-Direktive '#include' einfügen.
Header-Dateien dienen zwei Zwecken.
- Systemheaderdateien deklarieren die Schnittstellen zu Teilen des Betriebssystems. Sie fügen sie in Ihr Programm ein, um die Definitionen und Deklarationen bereitzustellen, die Sie zum Aufrufen von Systemaufrufen und Bibliotheken benötigen.
- Ihre eigenen Header-Dateien enthalten Deklarationen für Schnittstellen zwischen den Quelldateien Ihres Programms. Jedes Mal, wenn Sie eine Gruppe zusammengehöriger Deklarationen und Makrodefinitionen haben, die alle oder die meisten in mehreren verschiedenen Quelldateien benötigt werden, empfiehlt es sich, eine Headerdatei für sie zu erstellen.
Für den C-Präprozessor selbst unterscheidet sich eine Header-Datei jedoch nicht von einer Quelldatei.
Das Organisationsschema für Header- / Quellendateien ist einfach eine strenge und standardisierte Konvention, die von verschiedenen Softwareprojekten festgelegt wird, um eine Trennung zwischen Schnittstelle und Implementierung zu ermöglichen.
Obwohl dies vom C ++ - Standard selbst nicht formal durchgesetzt wird, wird die Einhaltung der Header- / Quelldatei-Konvention dringend empfohlen und ist in der Praxis bereits fast allgegenwärtig.
Beachten Sie, dass Header-Dateien als Projektdateistrukturkonvention durch die bevorstehende Funktion von Modulen ersetzt werden können, die zum Zeitpunkt des Schreibens (z. B. C ++ 20) noch in einem zukünftigen C ++ - Standard aufgenommen werden muss.
Basisbeispiel
Das folgende Beispiel enthält einen Codeblock, der in mehrere Quelldateien aufgeteilt werden soll, wie durch // filename
.
Quelldaten
// 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;
}
Header-Dateien werden dann von anderen Quelldateien eingeschlossen, die die von der Header-Schnittstelle definierte Funktionalität verwenden möchten, jedoch keine Kenntnis ihrer Implementierung erfordern (wodurch die Codekopplung reduziert wird). Das folgende Programm verwendet den Header my_function.h
wie oben definiert:
// 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;
}
Der Kompilierungsprozess
Da Header-Dateien häufig Teil eines Kompilierungsprozess-Workflows sind, führt ein typischer Kompilierungsprozess, der die Header- / Quelldatei-Konvention verwendet, normalerweise Folgendes aus.
Wenn sich die Header- und Quellcodedatei bereits im selben Verzeichnis befinden, führt ein Programmierer die folgenden Befehle aus:
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
Alternativ, wenn Sie main.cpp
in eine Objektdatei kompilieren main.cpp
und dann als letzten Schritt nur Objektdateien miteinander verknüpfen:
g++ -c my_function.cpp
g++ -c main.cpp
g++ main.o my_function.o
Vorlagen in Header-Dateien
Vorlagen erfordern die Erzeugung von Code zur Kompilierungszeit: Eine mit Vorlagen versehene Funktion wird beispielsweise effektiv in mehrere verschiedene Funktionen umgewandelt, sobald eine mit Vorlagen versehene Funktion durch Verwendung im Quellcode parametrisiert wird.
Dies bedeutet, dass Template-Funktionen, Member-Funktionen und Klassendefinitionen nicht an eine separate Quellcodedatei delegiert werden können, da jeder Code, der ein Templat-Konstrukt verwendet, Kenntnisse seiner Definition erfordert, um generell abgeleiteten Code zu generieren.
Daher muss in der Vorlage enthaltener Code auch seine Definition enthalten, wenn er in Headern eingefügt wird. Ein Beispiel dafür ist unten:
// 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;
}