Menu
Coddy logo textTech

Arithmetische Operatorüberladung

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

Arithmetische Operatoren wie +, -, * und / werden häufig überladen, damit sich benutzerdefinierte Klassen wie integrierte numerische Typen verhalten. Diese Operatoren geben in der Regel ein neues Objekt zurück, anstatt die Operanden zu ändern.

Hier ist eine Fraction-Klasse mit arithmetischen Operatoren:

class Fraction {
    int numerator, denominator;
    
public:
    Fraction(int n, int d) : numerator(n), denominator(d) {}
    
    Fraction operator+(const Fraction& other) const {
        return Fraction(
            numerator * other.denominator + other.numerator * denominator,
            denominator * other.denominator
        );
    }
    
    Fraction operator*(const Fraction& other) const {
        return Fraction(numerator * other.numerator, 
                        denominator * other.denominator);
    }
};

Beachten Sie, dass beide Operatoren als const markiert sind, da sie keinen der Operanden verändern. Sie erstellen und geben ein neues Fraction mit dem Ergebnis zurück.

Für Verbundzuweisungsoperatoren wie += unterscheidet sich das Muster. Diese modifizieren den linken Operanden und geben eine Referenz darauf zurück:

Fraction& operator+=(const Fraction& other) {
    numerator = numerator * other.denominator + other.numerator * denominator;
    denominator = denominator * other.denominator;
    return *this;
}

Eine gängige Praxis besteht darin, den Basisoperator auf Basis der Verbundzuweisung zu implementieren, um Codeduplizierung zu reduzieren:

Fraction operator+(const Fraction& other) const {
    Fraction result = *this;    // Dieses Objekt kopieren
    result += other;            // Verbundzuweisung verwenden
    return result;
}

Dieser Ansatz stellt sicher, dass beide Operatoren konsistent bleiben und erleichtert die Wartung.

challenge icon

Aufgabe

Einfach

Lassen Sie uns eine Money-Klasse erstellen, die Währungsberechnungen mittels Überladung von arithmetischen Operatoren verarbeitet. Sie werden mehrere arithmetische Operatoren implementieren, mit denen Sie mit Geldwerten so natürlich arbeiten können wie mit normalen Zahlen.

Sie werden zwei Dateien erstellen, um Ihren Code zu organisieren:

  • Money.h: Definieren Sie eine Money-Klasse, die einen Betrag in Cents (als int) speichert, um Probleme mit der Fließkommapräzision zu vermeiden. Ihre Klasse sollte Folgendes unterstützen:
    • Einen Konstruktor, der Dollar und Cents als separate Ganzzahlen entgegennimmt
    • Einen Getter getDollars(), der den Dollar-Anteil zurückgibt
    • Einen Getter getCents(), der den Cent-Anteil zurückgibt (0-99)
    • Überladene + und - Operatoren, die ein neues Money-Objekt zurückgeben
    • Überladene += und -= Verbundzuweisungsoperatoren, die das aktuelle Objekt ändern und eine Referenz darauf zurückgeben
    • Eine display()-Methode, die den Geldbetrag im Format $X.YY ausgibt (immer zwei Stellen für Cents)

    Implementieren Sie die Basisoperatoren (+ und -) unter Verwendung der Verbundzuweisungsoperatoren, um Code-Duplizierung zu reduzieren, wie in der Lektion gezeigt. Alle arithmetischen Operatoren sollten, wo angemessen, als const markiert werden.

  • main.cpp: Lesen Sie vier Ganzzahlen von der Eingabe ein, die zwei Geldbeträge repräsentieren (dollars1, cents1, dollars2, cents2 in separaten Zeilen). Erstellen Sie zwei Money-Objekte und demonstrieren Sie dann alle Ihre Operatoren:
    • Geben Sie "Amount 1: " gefolgt vom ersten angezeigten Betrag aus
    • Geben Sie "Amount 2: " gefolgt vom zweiten angezeigten Betrag aus
    • Addieren Sie die beiden Beträge und geben Sie "Sum: " gefolgt vom Ergebnis aus
    • Subtrahieren Sie den zweiten vom ersten und geben Sie "Difference: " gefolgt vom Ergebnis aus
    • Verwenden Sie +=, um den zweiten Betrag zum ersten zu addieren, und geben Sie dann "After +=: " gefolgt vom geänderten ersten Betrag aus

Verwenden Sie für die display()-Methode std::setw(2) und std::setfill('0') aus <iomanip>, um sicherzustellen, dass Cents immer zweistellig angezeigt werden (z. B. $5.07 statt $5.7).

Konvertieren Sie Eingabestrings mit std::stoi() in Ganzzahlen. Vergessen Sie nicht die Header-Guards in Ihrer Header-Datei.

Spickzettel

Arithmetische Operatoren wie +, -, * und / können überladen werden, damit sich benutzerdefinierte Klassen wie integrierte numerische Typen verhalten. Diese Operatoren geben normalerweise ein neues Objekt zurück, anstatt die Operanden zu verändern.

Grundlegende arithmetische Operatoren sollten als const markiert werden, da sie keinen der Operanden verändern:

Fraction operator+(const Fraction& other) const {
    return Fraction(
        numerator * other.denominator + other.numerator * denominator,
        denominator * other.denominator
    );
}

Zusammengesetzte Zuweisungsoperatoren wie += und -= verändern den linken Operanden und geben eine Referenz darauf zurück:

Fraction& operator+=(const Fraction& other) {
    numerator = numerator * other.denominator + other.numerator * denominator;
    denominator = denominator * other.denominator;
    return *this;
}

Eine gängige Praxis ist es, grundlegende Operatoren mithilfe von zusammengesetzten Zuweisungsoperatoren zu implementieren, um Code-Duplizierung zu reduzieren:

Fraction operator+(const Fraction& other) const {
    Fraction result = *this;    // Dieses Objekt kopieren
    result += other;            // Zusammengesetzte Zuweisung verwenden
    return result;
}

Probier es selbst

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

using namespace std;

int main() {
    // Eingabe für zwei Geldbeträge lesen
    string line;
    
    getline(cin, line);
    int dollars1 = stoi(line);
    
    getline(cin, line);
    int cents1 = stoi(line);
    
    getline(cin, line);
    int dollars2 = stoi(line);
    
    getline(cin, line);
    int cents2 = stoi(line);
    
    // TODO: Zwei Money-Objekte mit den Eingabewerten erstellen
    
    // TODO: "Amount 1: " gefolgt vom ersten angezeigten Betrag ausgeben
    
    // TODO: "Amount 2: " gefolgt vom zweiten angezeigten Betrag ausgeben
    
    // TODO: Die beiden Beträge addieren und "Sum: " gefolgt vom Ergebnis ausgeben
    
    // TODO: Den zweiten vom ersten Betrag subtrahieren und "Difference: " gefolgt vom Ergebnis ausgeben
    
    // TODO: += verwenden, um den zweiten Betrag zum ersten zu addieren, dann "After +=: " gefolgt vom geänderten ersten Betrag ausgeben
    
    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