In C++ darfst Du Deklarationen, die nur etwas ankündigen, beliebig oft wiederholen, alles andere dagegen nicht.
In Header-Dateien ist es unter anderem üblich, Struktur- alias Klassen-Definitionen als Schnittstellen zu definieren, darüber hinaus Konstanten.
All solches Zeug darf dem Compiler nur ein einziges Mal unter die Nase kommen.
Sobald Du das erste Mal selbst "richtig" Ausklammerungstechniken zur Vermeidung von Redundanzen anwendest (sprich: Bibliotheken für wiederverwendbaren Code schreibst), wirst Du merken, daß Du nicht Dinge nur aus einem konkreten Anwendungsprogramm in Bibliotheken verlagerst, sondern auch innerhalb Deiner Bibliotheken Dinge in verschiedene Ebenen auslagerst. Wobei viele relativ kleine und verzweigt ABHÄNGIGE Module entstehen.
Das führt dann dazu, daß eine CPP-Datei auf erste Sicht eine Handvoll Include-Dateien benötigt, jede davon aber wiederum eine Handvoll weiterer Include-Dateien, die wiederum auch noch weitere und so weiter - bis die auf der ganz untersten Ebene Deiner Bibliotheks-Hierarchie aufgelöst werden. DABEI wird es eher extrem SELTEN vorkommen, daß Deine Bibliotheksdateien auf den unteren Ebenen NICHT zig- oder gar hunderte Male für eine einzige CPP-Compilation included werden sollen. Es aber wegen den oben genannten Besonderheiten der C++-Syntax eben nur EINMAL dürfen.
Um Dir die Erstellung von solch tief strukturierten Bibliotheken zu ermöglichen, ohne daß Du einen Kollaps erleidest, andererseits aber auch den Compiler zufriedenzustellen, gibt es die Möglichkeit, Mehrfach-Includes auf Präprozessor-Ebene auszuschließen.
Das Prinzip ist ganz einfach: Du definierst irgendeine markante MARKE, die eine include-Datei eindeutig kennzeichnet, und definierst mittels "ifndef" folgendes:
Falls noch NICHT diese Marke definiert wurde (was bedeutet, daß diese include-Datei noch NICHT abgearbeitet wurde), läßt Du diese Datei abarbeiten - UND dabei AUCH jene markante Marke definieren.
Am sinnvollsten ist es zur Vermeidung von Namenskollisionen übrigens NICHT, diese Marke mit zwei, drei oder noch mehr Unterstrichen zu versehen, sondern sie mindestens nach dem Dateinamen in Zusammensetzung mit dem Namen der zugehörigen Bibliothek zu versehen. In etwa analog dem, was man in Java als Packages aufgezwungen kriegt, in C++ aber ohne weiteres auch freiwillig und mit maximaler Freiheit befolgen kann.