Menu
Coddy logo textTech

Friend-Funktionen und -Klassen

Teil des Abschnitts Objektorientierte Programmierung der C++-Journey von Coddy. Lektion 32 von 104.

Manchmal benötigt eine Funktion oder Klasse außerhalb deiner Klasse Zugriff auf ihre privaten Mitglieder. Anstatt diese Mitglieder öffentlich zu machen, stellt C++ das Schlüsselwort friend bereit, um selektiven Zugriff zu gewähren und gleichzeitig die Kapselung beizubehalten.

Eine Friend-Funktion wird innerhalb einer Klasse deklariert, ist aber kein Mitglied dieser Klasse. Sie kann auf die privaten und geschützten Mitglieder der Klasse zugreifen:

class Box {
    double width;
    
public:
    Box(double w) : width(w) {}
    
    // Deklariere printWidth als friend
    friend void printWidth(const Box& b);
};

// Friend-Funktionsdefinition – KEINE Member-Funktion
void printWidth(const Box& b) {
    std::cout << b.width;    // Kann auf privates Member zugreifen
}

Beachte, dass printWidth außerhalb der Klasse ohne den Operator zur Bereichsauflösung definiert ist. Es handelt sich um eine reguläre Funktion, die zufällig über besondere Zugriffsrechte verfügt.

Du kannst auch eine ganze Klasse zu einem Freund machen und dadurch allen ihren Memberfunktionen Zugriff auf private Member gewähren:

class Engine {
    int horsepower;
    
    friend class Mechanic;    // Mechanic kann auf private Member zugreifen
    
public:
    Engine(int hp) : horsepower(hp) {}
};

class Mechanic {
public:
    void diagnose(const Engine& e) {
        std::cout << e.horsepower;    // Erlaubt - Mechanic ist ein friend
    }
};

Freundschaft ist nicht gegenseitig – wenn Engine Mechanic als Freund deklariert, kann Mechanic auf die privaten Member von Engine zugreifen, aber nicht umgekehrt. Verwende Freunde sparsam, da sie eine enge Kopplung zwischen Klassen erzeugen. Sie sind besonders nützlich für die Operatorüberladung und eng verwandte Hilfsfunktionen.

challenge icon

Aufgabe

Einfach

Wir erstellen ein sicheres Nachrichtensystem, bei dem eine MessageReader-Klasse speziellen Zugriff benötigt, um verschlüsselte Nachrichten zu lesen, die in einer SecureMessage-Klasse gespeichert sind. Dies ist ein perfektes Szenario für die Verwendung von Freundfunktionen und Freundklassen.

Du erstellst zwei Dateien, um deinen Code zu organisieren:

  • SecureMessage.h: Definiere eine SecureMessage-Klasse, die private Nachrichtendaten speichert und vertrauenswürdigen Entitäten selektiven Zugriff gewährt. Deine Klasse sollte Folgendes enthalten:
    • Private Member: content (string) und secretKey (int)
    • Einen Konstruktor, der den Inhalt und den geheimen Schlüssel entgegennimmt
    • MessageReader als Freundklasse deklarieren, damit sie auf private Member zugreifen kann
    • Eine Freundfunktion decryptMessage(const SecureMessage& msg, int key) deklarieren, die den Inhalt nur zurückgibt, wenn der bereitgestellte Schlüssel mit dem geheimen Schlüssel übereinstimmt, andernfalls "Access Denied" zurückgibt

    Definiere anschließend die MessageReader-Klasse in derselben Header-Datei:

    • Eine Methode readContent(const SecureMessage& msg), die direkt auf den privaten content der Nachricht zugreift und ihn zurückgibt
    • Eine Methode verifyKey(const SecureMessage& msg, int key), die prüft, ob der bereitgestellte Schlüssel mit dem secretKey der Nachricht übereinstimmt, und "Valid" oder "Invalid" zurückgibt

    Definiere schließlich die Freundfunktion decryptMessage nach den Klassen.

  • main.cpp: Zeige sowohl Freundfunktionen als auch Freundklassen in Aktion. Lies einen Nachrichteninhalt, einen geheimen Schlüssel und einen Testschlüssel aus der Eingabe ein (jeweils in einer separaten Zeile), und:
    • Erstelle eine SecureMessage mit dem Inhalt und dem geheimen Schlüssel
    • Erstelle ein MessageReader-Objekt
    • Gib "Reader access: <content>" mithilfe der Methode readContent() des Readers aus
    • Gib "Key verification: <result>" mithilfe von verifyKey() mit dem Testschlüssel aus
    • Gib "Decrypt with test key: <result>" mithilfe der Freundfunktion mit dem Testschlüssel aus
    • Gib "Decrypt with correct key: <result>" mithilfe der Freundfunktion mit dem ursprünglichen geheimen Schlüssel aus

Denke daran, dass Freundfunktionen außerhalb der Klasse ohne den Bereichsauflösungsoperator definiert werden: Es handelt sich um normale Funktionen mit besonderen Zugriffsrechten. Die Klasse MessageReader kann als Freundklasse in all ihren Methoden direkt auf die privaten Member von SecureMessage zugreifen.

Konvertiere die Schlüsseleingaben mithilfe von std::stoi() von Zeichenketten in Ganzzahlen. Binde deine Header-Datei in main.cpp mithilfe von #include "SecureMessage.h" ein.

Probier es selbst

#include <iostream>
#include <string>
#include "SecureMessage.h"
using namespace std;

int main() {
    // Eingabe lesen
    string messageContent;
    string secretKeyStr;
    string testKeyStr;
    
    getline(cin, messageContent);
    getline(cin, secretKeyStr);
    getline(cin, testKeyStr);
    
    int secretKey = stoi(secretKeyStr);
    int testKey = stoi(testKeyStr);
    
    // TODO: Erstelle eine SecureMessage mit dem Inhalt und dem geheimen Schlüssel
    
    // TODO: Erstelle ein MessageReader-Objekt
    
    // TODO: Print "Reader access: <content>" using readContent()
    
    // TODO: Print "Key verification: <result>" using verifyKey() with test key
    
    // TODO: Print "Decrypt with test key: <result>" using decryptMessage with test key
    
    // TODO: Print "Decrypt with correct key: <result>" using decryptMessage with secret key
    
    return 0;
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-C++-Compiler