Menu
Coddy logo textTech

Überladung der Operatoren [] und ()

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

Der Indexoperator ([]) ermöglicht es Ihrer Klasse, sich wie ein Array zu verhalten, und bietet indizierten Zugriff auf Elemente. Der Funktionsaufruf-Operator (()) macht Objekte zu aufrufbaren Entitäten, bekannt als Funktoren.

Hier ist ein einfacher Array-Wrapper mit dem Subskript-Operator:

class IntArray {
    int* data;
    size_t size;
    
public:
    IntArray(size_t s) : size(s), data(new int[s]()) {}
    ~IntArray() { delete[] data; }
    
    int& operator[](size_t index) {
        return data[index];
    }
    
    const int& operator[](size_t index) const {
        return data[index];
    }
};

Beachte, dass wir zwei Versionen bereitstellen: Eine gibt eine nicht-konstante Referenz zurück (und ermöglicht Änderungen), während die const-Version mit const-Objekten funktioniert. Dadurch kannst du zum Lesen und Schreiben arr[0] = 5; schreiben.

Der Funktionsaufruf-Operator erzeugt Objekte, die wie Funktionen „aufgerufen“ werden können:

class Multiplier {
    int factor;
    
public:
    Multiplier(int f) : factor(f) {}
    
    int operator()(int value) const {
        return value * factor;
    }
};

Multiplier triple(3);
int result = triple(10);    // Gibt 30 zurück

Funktoren sind leistungsstark, weil sie im Gegensatz zu regulären Funktionen den Zustand zwischen Aufrufen beibehalten können. Sie werden häufig mit STL-Algorithmen verwendet, wenn Sie ein anpassbares Verhalten benötigen, das sich Konfigurationswerte merkt.

challenge icon

Aufgabe

Einfach

Erstelle eine ScoreTracker-Klasse, die sowohl den Subscript- als auch den Funktionsaufrufoperator kombiniert. Diese Klasse speichert die Punktzahlen der Spieler und ermöglicht den Zugriff über einen Index mit []. Gleichzeitig fungiert sie als Funktor, der auf jede übergebene Punktzahl einen Bonusmultiplikator anwendet.

Du erstellst zwei Dateien, um deinen Code zu organisieren:

  • ScoreTracker.h: Definiere eine ScoreTracker-Klasse, die ein Array mit den Punktzahlen der Spieler verwaltet und Boni anwenden kann. Deine Klasse sollte Folgendes enthalten:
    • Ein dynamisch reserviertes int*-Array zum Speichern der Punktzahlen
    • Ein size_t-Member für die Anzahl der Punktzahlen
    • Ein double-Member für den Bonusmultiplikator
    • Einen Konstruktor, der die Größe und den Bonusmultiplikator übernimmt und alle Punktzahlen mit 0 initialisiert
    • Einen Destruktor, der den dynamischen Speicher ordnungsgemäß freigibt
    • Den Subscript-Operator [] (sowohl in der const- als auch in der nicht-const-Version) für den Zugriff auf Punktzahlen über einen Index
    • Den Funktionsaufrufoperator (), der eine int-Punktzahl übernimmt und die mit dem Bonusmultiplikator multiplizierte Punktzahl (als int) zurückgibt
    • Eine getSize()-Methode, die die Anzahl der Punktzahlen zurückgibt

    Der nicht-const Subscript-Operator gibt eine Referenz zurück, sodass du tracker[0] = 100; schreiben kannst. Die const-Version ermöglicht den schreibgeschützten Zugriff für const-Objekte. Der Funktionsaufrufoperator sollte als const markiert werden, da er den Zustand des Objekts nicht verändert.

  • main.cpp: Lies die folgenden Eingaben ein (jeweils in einer eigenen Zeile):
    1. Anzahl der Spieler (Größe)
    2. Bonusmultiplikator (als double)
    3. Punktzahlen für jeden Spieler (eine pro Zeile, so viele wie die Größe angibt)
    4. Eine Testpunktzahl, auf die der Bonus angewendet werden soll

    Erstelle einen ScoreTracker, verwende den Subscript-Operator, um die Punktzahl jedes Spielers zu speichern, und gib anschließend alle Punktzahlen aus. Verwende schließlich den Funktionsaufrufoperator, um die Punktzahl mit angewendetem Bonus zu berechnen.

    Ausgabeformat:

    Player 0: <score>
    Player 1: <score>
    ...
    Bonus applied to <test_score>: <result>

Beispiel: Bei 3 Spielern, einem Multiplikator von 1.5, Punktzahlen von 100, 200, 150 und einer Testpunktzahl von 80:

Player 0: 100
Player 1: 200
Player 2: 150
Bonus applied to 80: 120

Verwende std::stoi() und std::stod() für die Konvertierung der Eingaben. Vergiss die Include-Guards in deiner Header-Datei nicht.

Probier es selbst

#include <iostream>
#include <string>
#include "ScoreTracker.h"

using namespace std;

// TODO: ScoreTracker-Konstruktor implementieren
ScoreTracker::ScoreTracker(size_t size, double multiplier) {
    // TODO: Member initialisieren und dynamisches Array allokieren
    // Alle Spielstände auf 0 initialisieren
}

// TODO: ScoreTracker-Destruktor implementieren
ScoreTracker::~ScoreTracker() {
    // TODO: Dynamischen Speicher bereinigen
}

// TODO: Nicht-konstanten Subscript-Operator implementieren

// TODO: Konstanten Subscript-Operator implementieren

// TODO: Funktionsaufruf-Operator implementieren

// TODO: getSize-Methode implementieren
size_t ScoreTracker::getSize() const {
    // TODO: Die Anzahl der Spielstände zurückgeben
}

int main() {
    string line;
    
    // Anzahl der Spieler einlesen
    getline(cin, line);
    size_t numPlayers = stoi(line);
    
    // Bonus-Multiplikator einlesen
    getline(cin, line);
    double multiplier = stod(line);
    
    // TODO: ScoreTracker mit numPlayers und multiplier erstellen
    
    // TODO: Spielstände für jeden Spieler einlesen und mit dem Subscript-Operator speichern
    
    // TODO: Test-Spielstand einlesen
    
    // TODO: Alle Spieler-Spielstände im Format "Player X: <score>" anzeigen
    
    // TODO: Ergebnis des angewendeten Bonus im Format "Bonus applied to <test_score>: <result>" anzeigen
    
    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