Welche Dinge sollten auf keinen Fall in einer Header-Datei enthalten sein?
Wenn ich zum Beispiel mit einem dokumentierten Industriestandardformat arbeite, das viele Konstanten enthält, ist es eine gute Praxis, diese in einer Headerdatei zu definieren (wenn ich einen Parser für dieses Format schreibe)?
Welche Funktionen sollen in die Header-Datei gehen?
Welche Funktionen sollten nicht?
Antworten:
Was in Überschriften zu setzen:
#include
Anweisungen, die erforderlich sind, um den Header kompilierbar zu machen, wenn der Header in einer Quelldatei enthalten ist.Was nicht in einen Header gehört:
#include
Weisungen. Diese unentgeltlichen Includes verursachen eine Neukompilierung von Dingen, die nicht neu kompiliert werden müssen, und können es manchmal so machen, dass ein System nicht kompiliert werden kann. Keine#include
Datei in einem Header, wenn der Header selbst diese andere Headerdatei nicht benötigt.#include
ist, die geändert werden kann oder die zu groß sind. Diese Inline-Funktionen sollten wenig oder gar keinen Fan-Out haben, und wenn sie Fan-Out haben, sollten sie auf die im Header definierten Elemente lokalisiert werden.Was macht die minimale Menge von
#include
Aussagen aus?Dies stellt sich als nicht triviale Frage heraus. Eine TL; DR-Definition: Eine Header-Datei muss die Header-Dateien enthalten, die direkt jeden der direkt in der betreffenden Header-Datei verwendeten Typen definieren oder die direkt jede der in der betreffenden Header-Datei verwendeten Funktionen deklarieren, darf jedoch nichts anderes enthalten. Ein Zeiger- oder C ++ - Referenztyp gilt nicht als direkte Verwendung. Vorwärtsreferenzen werden bevorzugt.
Es gibt einen Platz für eine unbegründete
#include
Anweisung, und dies erfolgt in einem automatisierten Test. Für jede Header-Datei in einem Softwarepaket erstelle und kompiliere ich automatisch Folgendes:Die Kompilierung sollte sauber sein (dh frei von Warnungen oder Fehlern). Warnungen oder Fehler in Bezug auf unvollständige oder unbekannte Typen bedeuten, dass in der zu testenden Header-Datei einige
#include
Anweisungen und / oder Vorwärtserklärungen fehlen. Gut zu beachten: Nur weil der Test bestanden wurde, bedeutet dies nicht, dass der#include
Richtliniensatz ausreicht, geschweige denn minimal.quelle
Zusätzlich zu dem, was bereits gesagt wurde.
H-Dateien sollten immer enthalten:
H-Dateien sollten niemals enthalten:
static
.(Ich würde auch sagen, dass es nie einen Grund gibt, nicht konstante globale / externe Variablen zu verwenden, aber das ist eine Diskussion für einen anderen Beitrag.)
quelle
Ich würde wahrscheinlich nie nie sagen, aber Anweisungen, die Daten und Code generieren, während sie analysiert werden, sollten nicht in einer .h-Datei enthalten sein.
Makros, Inline-Funktionen und Vorlagen sehen möglicherweise wie Daten oder Code aus, generieren jedoch keinen Code, wenn sie analysiert werden, sondern wenn sie verwendet werden. Diese Elemente müssen häufig in mehr als einer .c- oder .cpp-Datei verwendet werden, sodass sie in die .h-Datei gehören.
Meiner Ansicht nach sollte eine Header-Datei die minimale praktische Schnittstelle zu einer entsprechenden .c- oder .cpp-Datei haben. Die Schnittstelle kann #defines, class, typedef, Strukturdefinitionen, Funktionsprototypen und weniger bevorzugte externe Definitionen für globale Variablen enthalten. Wenn eine Deklaration jedoch nur in einer Quelldatei verwendet wird, sollte sie wahrscheinlich aus der .h-Datei ausgeschlossen und stattdessen in der Quelldatei enthalten sein.
Einige mögen anderer Meinung sein, aber mein persönliches Kriterium für .h-Dateien ist, dass sie alle anderen .h-Dateien enthalten, die sie kompilieren müssen. In einigen Fällen kann dies eine Vielzahl von Dateien sein. Daher verfügen wir über einige effektive Methoden, um externe Abhängigkeiten wie Forward-Deklarationen für Klassen zu reduzieren, mit denen wir Zeiger auf Objekte einer Klasse verwenden können, ohne einen möglicherweise großen Baum von Include-Dateien einzuschließen.
quelle
Die Header-Datei sollte die folgende Organisation haben:
Header-Dateien sollten niemals Objektdefinitionen, sondern nur Typdefinitionen und Objektdeklarationen enthalten.
quelle
Anweisungen, die beim Parsen Daten und Code generieren, sollten nicht in einer
.h
Datei enthalten sein. Aus meiner Sicht sollte eine Header-Datei nur die minimale praktische Schnittstelle zu einem entsprechenden.c
oder haben.cpp
.quelle