"Parametrisierte" Header-Dateien können verwendet werden, um C ++ - ish-artige Vorlagen in C zu simulieren. In solchen Fällen hängt die Header-Datei von einer Anzahl von Makros ab ("Template-Parameter"). Abhängig vom tatsächlichen "Wert" dieser Makros wird ein anderer Code generiert.
Die typische Verwendung eines solchen Headers würde also als eine Folge von "template parameter" Makrodefinitionen aussehen, gefolgt von der #include
Direktive, gefolgt von einer anderen Sequenz von "template parameter" Makrodefinitionen, gefolgt von der gleichen #include
, und so weiter.
Wenn Sie diese Technik verwenden, sehen Sie Header-Dateien ohne Include-Wächter oder Header-Dateien mit Include-Wachen, die nur einen Teil der Datei abdecken.
In C:
%Vor% Spülen und wiederholen. Das Analog in C ++ verwendet stattdessen den Header <cassert>
.
Manchmal gibt es also Gründe, einen Header zweimal einzubeziehen. Nicht oft, aber es gibt Gründe dafür.
Fälle wie diese sind selten, und wenn sie existieren, ist ein Re-Design sowieso besser geeignet. Eine, die ich mir vorstellen kann, sind Header, die Deklarationen anhäufen:
%Vor% Das würde nicht funktionieren, wenn functions.h
Wachen enthält, aber das ist wiederum ziemlich peinlicher Code ...
Stellen Sie sich vor, Sie schreiben Ihren eigenen Template-Array-Wrapper (Elemente sind Pointer) für Ihre winzige Engine, wobei Array entweder:
sein kanndamit kannst du entweder eine Klasse erstellen, in der das alles gehandhabt wird, aber es würde immer prüfen, was wir tun können oder was nicht. Am besten ist es, separate Klassen zu erstellen, aber hier haben wir so viel gleichen Code zwischen ihnen können Sie (wenn nicht vorsichtig) entweder einen Fehler in einer der Funktionen machen und das Hinzufügen einer neuen Funktion wäre langsamer.
Am besten ist es, die "parametrisierten" Header-Dateien zu verwenden (wie von AnT angegeben) und einfach Klassen wie
zu erstellenCodebeispiel:
// TestDfM.h
%Vor%// TestDf.h
%Vor%// Haupt.cpp
%Vor%Header-Dateien werden nur textuell eingefügt, wenn sie gefunden werden. Es gibt keinen wirklichen Grund, warum sie nicht mehr als einmal aufgenommen werden können. Wenn Header nur für die Deklaration und keine Definitionen verwendet werden (und keine Deklarationen von Templates mit Standardargumenten), ist es nicht einmal problematisch, sie mehr als einmal einzubeziehen.
Das heißt <cassert>
ist das kanonische Beispiel für das mehrfache Einfügen einer Datei: Sie können die Definition von NDEBUG
ändern und ein anderes Verhalten vom assert()
-Makro innerhalb einer Übersetzungseinheit erhalten.
Nun ist etwas wie include_once
, das eine Datei nur einmal enthält, nicht so trivial wie die Leute denken. Hier ist ein Beispiel, in dem nicht klar ist, wie oft foo.h
enthalten sein sollte:
Wenn include_once
jede Datei nur einmal enthält, wie oft sollte foo.h
enthalten sein? Alle drei Dateien können sich leicht auf die gleiche physische Datei beziehen, aber dies ist möglicherweise nicht ohne weiteres sichtbar, z. B. weil ein Link zu einem anderen ist. Es scheint am besten, dem Programmierer die Kontrolle zu geben, wie kontrolliert werden kann, wie oft sie benutzt werden.