Das Schlüsselwort friend ermöglicht einer bestimmten Funktion oder einer anderen Klasse den Zugriff auf die privaten und geschützten Mitglieder der Klasse, in der friend deklariert ist. Friend-Funktionen können sowohl global als auch Methoden anderer Klassen sein. Diese Konstruktion ermöglicht es, Funktionen zu implementieren, die Zugriff auf den internen Zustand der Klasse benötigen, aber logisch nicht mit dem Interface dieser Klasse verbunden sind.
Es wird empfohlen, friend zu verwenden:
Achtung:
Beispiel:
class Box { int width; public: Box(int w): width(w) {} friend void printWidth(const Box &b); }; void printWidth(const Box &b) { std::cout << b.width << std::endl; }
Frage: Kann eine friend-Funktion virtuell sein?
Häufige Antwort: Ja, da friend ein Modifikator für Funktionen ist.
Richtige Antwort: Nein, friend-Funktionen können nicht virtuell sein, weil sie keine Mitglieder der Klasse sind!
Beispiel:
class Example { friend virtual void foo(); // Kompilierungsfehler: virtual gilt nicht für friend };
Geschichte: Bei der Entwicklung einer Matrixbibliothek wurden alle arithmetischen Operatoren als friend-Funktionen implementiert, um die Geschwindigkeit zu erhöhen, jedoch wurde die Unterstützung der Konstantheit vergessen und der Zugriff auf private Mitglieder übermäßig geöffnet. Später gab es das Problem, dass andere Funktionen versehentlich den inneren Zustand der Matrix änderten.
Geschichte: In einem Unternehmenssystem wurden Hilfsklassen zu Freunden von einander gemacht, um den Zugriff auf private Mitglieder zu teilen. Dies führte zu zyklischen Abhängigkeiten – das Hinzufügen einer neuen Funktion erforderte Änderungen an allen verbundenen Klassen. Die anschließende Refaktorisierung dauerte Wochen.
Geschichte: Für geschlossene Tests wurde entschieden, dass die Testklasse ein Freund der Produktionsklasse wird. Als mehrere Sätze von Unit-Tests erschienen, wurde es unmöglich zu verfolgen, welche privaten Methoden tatsächlich verwendet wurden – die Tests begannen, von der internen Implementierung abhängig zu sein, was die Wartung des Codes erschwerte.