Menu
Coddy logo textTech

Przeciążanie operatorów arytmetycznych

Część sekcji Programowanie obiektowe ścieżki C++ w Coddy. Lekcja 41 z 104.

Operatory arytmetyczne, takie jak +, -, * i /, są często przeciążane, aby klasy niestandardowe zachowywały się jak wbudowane typy numeryczne. Operatory te zazwyczaj zwracają nowy obiekt, zamiast modyfikować operandy.

Oto klasa Fraction z operatorami arytmetycznymi:

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);
    }
};

Zauważ, że oba operatory są oznaczone jako const, ponieważ nie modyfikują żadnego z operandów. Tworzą nowy obiekt Fraction z wynikiem i go zwracają.

W przypadku operatorów przypisania złożonego, takich jak +=, wzorzec jest inny. Modyfikują one lewy operand i zwracają do niego referencję:

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

Częstą praktyką jest implementowanie podstawowego operatora za pomocą operatora przypisania złożonego, co ogranicza duplikację kodu:

Fraction operator+(const Fraction& other) const {
    Fraction result = *this;    // Skopiuj ten obiekt
    result += other;            // Użyj przypisania złożonego
    return result;
}

To podejście zapewnia spójność obu operatorów i ułatwia konserwację.

challenge icon

Wyzwanie

Łatwy

Stwórzmy klasę Money, która obsługuje obliczenia walutowe za pomocą przeciążania operatorów arytmetycznych. Zaimplementujesz kilka operatorów arytmetycznych, które pozwolą Ci operować na wartościach pieniężnych równie naturalnie jak na zwykłych liczbach.

Utworzysz dwa pliki, aby uporządkować swój kod:

  • Money.h: Zdefiniuj klasę Money, która przechowuje kwotę w centach (jako int), aby uniknąć problemów z precyzją liczb zmiennoprzecinkowych. Klasa powinna obsługiwać:
    • Konstruktor, który przyjmuje dolary i centy jako osobne liczby całkowite
    • Getter getDollars(), który zwraca część kwoty wyrażoną w dolarach
    • Getter getCents(), który zwraca część kwoty wyrażoną w centach (0-99)
    • Przeciążone operatory + i -, które zwracają nowy obiekt Money
    • Przeciążone operatory przypisania złożonego += i -=, które modyfikują bieżący obiekt i zwracają do niego referencję
    • Metodę display(), która wyświetla kwotę w formacie $X.YY (centy zawsze jako dwie cyfry)

    Zaimplementuj podstawowe operatory (+ i -) za pomocą operatorów przypisania złożonego, aby ograniczyć powielanie kodu, tak jak pokazano w lekcji. Wszystkie operatory arytmetyczne powinny być oznaczone jako const tam, gdzie to właściwe.

  • main.cpp: Odczytaj z wejścia cztery liczby całkowite reprezentujące dwie kwoty pieniężne (dollars1, cents1, dollars2, cents2 w osobnych wierszach). Utwórz dwa obiekty Money, a następnie zademonstruj działanie wszystkich operatorów:
    • Wyświetl "Amount 1: ", a następnie pierwszą kwotę
    • Wyświetl "Amount 2: ", a następnie drugą kwotę
    • Dodaj obie kwoty i wyświetl "Sum: ", a następnie wynik
    • Odejmij drugą kwotę od pierwszej i wyświetl "Difference: ", a następnie wynik
    • Użyj +=, aby dodać drugą kwotę do pierwszej, a następnie wyświetl "After +=: ", a po nim zmodyfikowaną pierwszą kwotę

W metodzie display() użyj std::setw(2) i std::setfill('0') z <iomanip>, aby centy były zawsze wyświetlane jako dwie cyfry (np. $5.07, a nie $5.7).

Konwertuj ciągi wejściowe na liczby całkowite za pomocą std::stoi(). Nie zapomnij o strażnikach nagłówka w pliku nagłówkowym.

Spróbuj swoich sił

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

using namespace std;

int main() {
    // Wczytaj dane dla dwóch kwot
    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: Utwórz dwa obiekty Money z wartościami wejściowymi
    
    // TODO: Wypisz "Amount 1: ", a następnie wyświetl pierwszą kwotę
    
    // TODO: Wypisz "Amount 2: ", a następnie wyświetl drugą kwotę
    
    // TODO: Dodaj obie kwoty i wypisz "Sum: ", a następnie wynik
    
    // TODO: Odejmij drugą kwotę od pierwszej i wypisz "Difference: ", a następnie wynik
    
    // TODO: Użyj +=, aby dodać drugą kwotę do pierwszej, a następnie wypisz "After +=: " i zmodyfikowaną pierwszą kwotę
    
    return 0;
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator C++ online