簡體   English   中英

重載算術運算符c ++

[英]overloading arithmetic operators c++

我剛開始學習C ++類,但是在處理重載算術運算符時遇到了很多問題。 首先,在我的頭文件中,我有:

#ifndef MONEY_H
#define MONEY_H
#include <iostream>
using namespace std;

class Money{
    public:
        Money(int dollars, int cents);
        Money(int dollars);
        Money();
        int getDollars() const {return dollars;};
        int getCents() const {return cents;};
        void setDollarsAndCents(int dollars, int cents);
        double getAmount() const {return amount ;};
        void setAmount(double amount);

        // Define operator functions  for comparison operators
        friend bool operator==(const Money& firstAmount, const Money& secondAmount);
        friend bool operator<(const Money& firstAmount, const Money& secondAmount);
        friend bool operator>(const Money& firstAmount, const Money& secondAmount);

        //Define operator functions for arithmetic operators
        friend Money operator+(const Money& firstAmount, const Money& secondAmount);
        friend Money operator-(const Money& firstAmount, const Money& secondAmount);
        friend Money operator*(const Money& money, int n);
        friend Money operator/(const Money& money, int n);

        //Define the output and input operator
        friend ostream& operator<<(ostream& outStream, const Money& money);
    private:
        int dollars, cents;
        double amount;
};
#endif

然后我在一個實現文件Money.cpp上實現了operator +

  #include "Money.h"

// Construct a money object with dollars and cents
Money::Money(int newDollars, int newCents)
{
    dollars = newDollars;
    cents = newCents;
}
// Construct a money object with JUST the dollars
Money::Money(int newDollars)
{
    dollars = newDollars;
    cents = 0;
}
// Construct a money object with no arguments (default amount = 0)
Money::Money()
{
    amount = 0.0;
}
// Set dollars and cents
void Money::setDollarsAndCents(int newDollars, int newCents)
{
    dollars = newDollars;
    cents = newCents;
}
// Set monetary amount
void Money::setAmount(double newAmount)
{
    //convert cents automatically if >= 100
    newAmount = dollars + cents/100.0;
    amount = newAmount;
}
// Test if two Money objects are equal or not
bool operator==(const Money& firstAmount, const Money& secondAmount)
{   
    return (firstAmount.amount == secondAmount.amount);
}
// Test if the first operand is less than the second operand
bool operator<(const Money& firstAmount, const Money& secondAmount)
{
    return (firstAmount.amount < secondAmount.amount);
}
// Test if the first operand is greater than the second operand
bool operator>(const Money& firstAmount, const Money& secondAmount) 
{
    return (firstAmount.amount > secondAmount.amount);
}
// Add two Money objects
Money operator+(const Money& firstAmount, const Money& secondAmount)
{
    //assume cents < 100
    int carry = 0;
    int finalCents = firstAmount.cents + secondAmount.cents;

    if (finalCents >= 100){
        carry += 1;
        finalCents -= 100;
    }
    int finalDollars = firstAmount.dollars + secondAmount.dollars + carry;

    return Money(finalDollars, finalCents);
}
// Subtract two Money objects
Money operator-(const Money& firstAmount, const Money& secondAmount)
{
    int borrow = 0;
    int finalCents = firstAmount.cents - secondAmount.cents;
    if (finalCents < 0){
        finalCents += 100;
        borrow = 1;
    }
    int finalDollars = firstAmount.dollars - secondAmount.dollars - borrow;
    return Money(finalDollars, finalCents);
}
// Multiply two Money objects
Money operator*(const Money& money, int n)
{
    return money.amount * n;
}
// Divide two Money objects
Money operator/(const Money& money, int n)
{
    int quotient = money.amount / n;
    // check if there isn't a remainder
    if ( quotient * n == 0)
        return money.amount / n;
    else // there's a remainder
        return money.dollars / n + money.cents / (n * 100);
}
// Define the output operator
ostream& operator<<(ostream& outputStream, const Money& money)
{
    outputStream << money.amount;
   return outputStream;
}

最后,在我的TestMoney.cpp的main方法中,我有:

#include "Money.h"
using namespace std;

int main()
{
    Money m1(-35),m2(53, 35);

    //Test operator == (false)
    cout << "m1 == m2 = " << (m1 == m2 ? "true" : "false")  << endl;

    Money m3(-35),m4(35); 

    //Test operator < (true)
    cout << "m3 < m4 = " << (m3 < m4 ? "true" : "false")  << endl;

    Money m5(-35),m6(53, 35); 

    //Test operator > (false)
    cout << "m5 > 6 = " << (m5 > m6 ? "true" : "false")  << endl;

    Money m7(12,50),m8(25,55); 
    // $12.50 & $25.50 = $38.05
    //Test operator +
    cout << "m7 + m8 = $" << (m7 + m8) << endl;

    //~ Money m9(5,75), m10(100); 
    //~ // $5.75 - $100 = $-94.25
    //~ //Test operator -
    //~ cout << "m9 - m10 = $" << m9 - m10 << endl;

    //~ Money m11(25,75);
    //~ int n = 5;
    //~ // $25.75 * $5 = $128.75
    //~ //Test operator *
    //~ cout << "m11 * m12 = $" << m11 * n << endl;

    //~ Money m13(115,75);
    //~ n = 3;
    //~ // $115.75 / $3 = $38.58333
    //~ //Test operator /
    //~ cout << "m13 / n = $" << m13 / n << endl;
    return 0;

}

顯然,我得到了答案: m7 + m8 = $4.94066e-324 答案應該是$ 38.05。

我已經在這里停留了一段時間了。 如果有人可以耐心地解釋我搞砸的地方,那就太好了。 謝謝您的幫助。

在這種情況下,您使用的構造函數重載不會設置'amount'。

Money::Money(int newDollars, int newCents)
{
    dollars = newDollars;
    cents = newCents;
}

您的operator+也不operator+

Money operator+(const Money& firstAmount, const Money& secondAmount)
{
    //assume cents < 100
    int carry = 0;
    int finalCents = firstAmount.cents + secondAmount.cents;

    if (finalCents >= 100){
        carry += 1;
        finalCents -= 100;
    }
    int finalDollars = firstAmount.dollars + secondAmount.dollars + carry;

    return Money(finalDollars, finalCents);
}

您的operator<<顯示amount ,並且尚未初始化。

您應該在所有構造函數重載中設置amount 最好讓它們都調用一個在一個地方進行初始化的私有函數來最好地實現。

更好地擺脫了以2種表示形式(美元/美分和金額)存儲值的重復性。 僅將其存儲為一個或另一個,它將變得更加容易維護。

還要注意,如果調用no args構造函數,則$和cents成員變量同樣會被初始化。

問題是您的operator <<輸出了amount成員。 但是它尚未初始化:

// Define the output operator
ostream& operator<<(ostream& outputStream, const Money& money)
{
    outputStream << money.amount;  // not initialized
    return outputStream;
}

如果你看看你coutmain ,你有這樣的:

(m7 + m8)

這將返回一個臨時的Money對象,該對象將被復制構造(不是默認構造)。 復制構造函數是由編譯器生成的(可以,但是請參見下面的評論)。 由於m7m8都設置了amount ,因此您將垃圾值復制到臨時Money對象,即垃圾值。


此外,由於未初始化double變量的amount ,您的代碼調用了未定義的行為,並且編譯器生成了將垃圾雙精度值復制到另一個double的副本構造函數。 除非操縱涉及初始化變量,否則您永遠不要嘗試操縱未初始化的浮點變量。

最重要的是,在構造對象時,應努力將所有成員初始化為定義的狀態。 是否使指針為NULL,是否使double等於0,等等。您的成員變量應設置為有效狀態。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM