Money.h
#pragma once
#include <string>
class Money {
private:
    long pounds;
    int pence;
public:
    Money();
    // Overloaded constructors
    explicit Money(long pounds);
    Money(long pounds, int pence);
    /* Overload operators to allow easier arithmetic of money objects, we will
     not overload * or / as it does not make logical sense for money to be multiplied
     or divided.
    */
    Money operator+(const Money& moneyRhs) const;
    Money operator-(const Money& moneyRhs) const;
    friend std::ostream& operator<<(std::ostream& os, const Money& money);
    // toString method to print out money object
    std::string toString() const;
    // Getters
    long getPounds() const;
    int getPence() const;
};
Money.cpp
#include "Money.h"
#include <iomanip>
Money::Money(): pounds(0), pence(0) {}
Money::Money(const long pounds): pounds(pounds), pence(0) {}
Money::Money(const long pounds, const int pence): pounds(pounds), pence(pence) {}
Money Money::operator+(const Money& moneyRhs) const {
    // Convert all money to pence then do addition
    const long poundsInPence = (pounds + moneyRhs.pounds) * 100;
    const int totalPence = pence + moneyRhs.pence;
    const long allPence = poundsInPence + totalPence;
    const Money m3 = Money(allPence / 100, allPence % 100);
    return m3;
}
Money Money::operator-(const Money& moneyRhs) const {
    // Convert all money to pence then do subtraction
    const long poundsInPence = (pounds - moneyRhs.pounds) * 100;
    const int totalPence = pence - moneyRhs.pence;
    const long allPence = poundsInPence + totalPence;
    const Money m3 = Money(allPence / 100, allPence % 100);
    return m3;
}
std::string Money::toString() const {
    std::string strMoneyFormat;
    // Check so see if the pence value is 1 digit, if so we need to add a trailing 0 for output
    // e.g £150.5 becomes £150.05
    if((getPence() > 0 ? static_cast<int>(log10(static_cast<double>(getPence()))) + 1 : 1) < 2) {
        strMoneyFormat = std::to_string(getPounds()) + "." + "0" + std::to_string(getPence());
    }
    else {
        strMoneyFormat = std::to_string(getPounds()) + "." + std::to_string(getPence());
    }
    return strMoneyFormat;
}
std::ostream& operator<<(std::ostream& os, const Money& money) {
    os << money.toString();
    return os;
}
long Money::getPounds() const {
    return pounds;
}
int Money::getPence() const {
    return pence;
}
I have the above money class implementation for a basic UK banking app, however, I know in coding, in general, it's best practice if you overload one type of operator e.g arithmetic you should overload its others as well, so here I have overloaded the + and -, so I need to overload / and *. However, it doesn't make much sense to multiply or divide the money, is there a way i can go about overloading these to operators that anyone knows, that would make sense?
Update:
template <class T>
    Money operator*(T number) const {
        const int penceMult = pence * number;
        const int newPence = penceMult % 100;
        const long newPounds = pounds * number + (penceMult / 100);
        Money tmp(newPounds, newPence);
        return tmp;
    }
    template <class T>
    Money operator/(T number) const {
        if (number == 0) {
            throw std::invalid_argument("Division by zero");
        }
        long total = (100 * pounds) + pence;
        const long result = total / number;
        const int newPence = result % 100;
        const long newPounds = result / 100;
        Money tmp(newPounds, newPence);
        return tmp;
    }
Aucun commentaire:
Enregistrer un commentaire