Friend-Funktion

aus Wikipedia, der freien Enzyklopädie
Zur Navigation springen Zur Suche springen

Unter einer Friend-Funktion oder Friend-Methode versteht man in der objektorientierten Programmierung eine Methode, Funktion oder Prozedur, der man erlaubt, auf private (private) oder geschützte (protected) Daten einer anderen Klasse zuzugreifen, auf die sie sonst keinen Zugriff hätte.

Ein solcher Zugriff widerspricht dem Paradigma der Datenkapselung, kann aber unter Umständen trotzdem sinnvoll sein. Dann wird die zugreifende Methode mit dem Schlüsselwort friend als ein „Freund“ der darauf zugegriffenen Klasse deklariert. Sie hat dann nicht nur auf öffentliche (public), sondern auch auf geschützte (protected) oder private (private) Informationen in dieser Klasse Zugriff.

Diese Möglichkeit der Freundschaft sollte mit Bedacht genutzt werden, da dadurch die Datenkapselung abgeschwächt wird. Friend-Methoden sind ein Konzept der Programmiersprache C++. Jedoch gibt es ähnliche Möglichkeiten in anderen objektorientierten Programmiersprachen (zum Beispiel internal in C#).

Beispiel 1

In diesem C++-Beispiel ist die Funktion main() ein Freund der Klasse A. Sie kann deshalb auf das mit private geschützte Attribut wert dieser Klasse zugreifen. Wäre main() nicht als Freund deklariert, wäre ein Zugriff auf das private Attribut nicht möglich und das Programm könnte auch nicht übersetzt werden.

Eine in der Praxis vorzuziehende Lösung wäre in diesem Beispiel eine Zugriffsfunktion.

#include <iostream>

class A {
private:
   int wert;
public:
   A() : wert(42) {}
   friend int main();
};

int main() {
   A a;

   std::cout << "A::wert = " << a.wert << std::endl;
}

Beispiel 2

In C++ können Operatoren überladen werden. So z. B. auch bei der Ausgabeoperator <<(ursprünglich logische Verschiebung). Wenn man eigene Datentypen implementiert, kann man durch Überladen dieses Operators die Ausgabe steuern. Dafür wird häufig der Zugriff auf private Member erfordert, die normalerweise für den Operator << nicht zugänglich sind.

Indem man den global überladenen Operator mit friend kennzeichnet, können jedoch auch private Attribute ausgegeben werden:

#include <iostream>
using namespace std;

class Zahl {
private:
    int m_zahl{20};
public:
    Zahl(){};
    Zahl(int zahl) : m_zahl(zahl){}

    friend ostream& operator<<(ostream &out, const Zahl &zahlObj){
        out << "Zahl: " << zahlObj.m_zahl;
        return out;
    }
};

int main(){
    Zahl zahl{5}
    cout << zahl << endl; //Ausgabe: Zahl: 5
}

Es ist zu beachten, dass, obwohl dieser Operator innerhalb der Klasse Zahl definiert ist, er eine freie Funktion darstellt, d. h. keine Memberfunktion der Klasse Zahl ist. Lässt man das Schlüsselwort friend weg, so wird operator<< zu einer Memberfunktion, was jedoch für dieses Beispiel zur Standardausgabe nicht sinnvoll wäre.

Anstelle einer Methode kann auch eine ganze Klasse als Freund einer anderen Klasse definiert werden. Dann kann jede Methode dieser Klasse auf alle privaten Informationen der anderen Klasse zugreifen.

class A
{
    
    friend class B;
};

class B
{
    
    void changeA(A &a) { a.a = b; }
};

int main()
{
    A a(100);
    B b(200);
    a.show(); // Gibt "a = 100" aus
    b.show(); // Gibt "b = 200" aus
    b.changeA(a);
    a.show(); // Gibt "a = 200" aus
    b.show(); // Gibt "b = 200" aus
}