Die erste Regel schlägt fehl, sobald es zirkuläre Abhängigkeiten gibt. Sie kann also nicht strikt angewendet werden.
(Das lässt sich zwar bewerkstelligen, verlagert aber eine ganze Menge Arbeit vom Programmierer auf den Nutzer dieser Bibliotheken, was offensichtlich falsch ist).
Ich bin für Regel 2 (obwohl es vielleicht gut wäre, "Vorwärtserklärungs-Kopfzeilen" anstelle der echten Kopfzeilen aufzunehmen, wie in <iosfwd>
weil dies die Kompilierzeit verkürzt). Generell halte ich es für eine Art Selbstdokumentation, wenn eine Header-Datei "deklariert", welche Abhängigkeiten sie hat - und wie könnte man das besser tun, als die benötigten Dateien einzubinden?
EDIT:
In den Kommentaren wurde mir entgegengehalten, dass zirkuläre Abhängigkeiten zwischen Kopfzeilen ein Zeichen für schlechtes Design sind und vermieden werden sollten.
Das ist nicht richtig. In der Tat, zirkuläre Abhängigkeiten zwischen den Klassen können unvermeidlich sein und sind keineswegs ein Zeichen für schlechtes Design. Beispiele gibt es viele, ich möchte nur das Beobachter-Muster erwähnen, das einen kreisförmigen Bezug zwischen dem Beobachter und dem Subjekt aufweist.
Um die Zirkularität zwischen Klassen aufzulösen, müssen Sie eine Vorwärtsdeklaration verwenden, da die Reihenfolge der Deklaration in C++ wichtig ist. Nun ist es durchaus akzeptabel, diese Vorwärtsdeklaration zirkulär zu behandeln, um die Anzahl der Gesamtdateien zu reduzieren und den Code zu zentralisieren. Zugegeben, der folgende Fall passt nicht zu diesem Szenario, da es nur eine einzige Vorwärtsdeklaration gibt. Ich habe jedoch an einer Bibliothek gearbeitet, in der dies viel häufiger der Fall war.
// observer.hpp
class Observer; // Forward declaration.
#ifndef MYLIB_OBSERVER_HPP
#define MYLIB_OBSERVER_HPP
#include "subject.hpp"
struct Observer {
virtual ~Observer() = 0;
virtual void Update(Subject* subject) = 0;
};
#endif
// subject.hpp
#include <list>
struct Subject; // Forward declaration.
#ifndef MYLIB_SUBJECT_HPP
#define MYLIB_SUBJECT_HPP
#include "observer.hpp"
struct Subject {
virtual ~Subject() = 0;
void Attach(Observer* observer);
void Detach(Observer* observer);
void Notify();
private:
std::list<Observer*> m_Observers;
};
#endif