运算符超载问题加法 [英] overloading operators issue with addition

查看:89
本文介绍了运算符超载问题加法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

添加对象时遇到问题.加上两个,例如:2.34 + 34.57 = 36.81,似乎可以工作,但是如果加上三个或三个以上的例子:6.78 + 9.81 + 4.59 = 79.59<-失败,总数似乎由于某种原因而急剧增加.

Having issues with adding objects. It seems to work when adding two, ex: 2.34 + 34.57 = 36.81, but fails when adding 3 or more ex: 6.78 + 9.81 + 4.59 = 79.59 <-- the total seems to increase drastically for some reason.

转换器函数可以忽略,因为它们只是将数字总数转换为英文格式并且可以正常工作.中位数和排序以及>函数也可以正常工作,因此问题可能出在ostream,istream或+函数中.我使用了cout一堆地方,大多数异常数字似乎都出现在+函数中.

The converter functions can be ignored since they simply translate the numerical total to english format and are working. The median and sorting, and > functions work as well, so the issue might be somewhere in the ostream, istream, or + functions. I used cout a whole bunch of places and most of the abnormal numbers seems to appear in the + function.

先谢谢了.

标题:

#ifndef LAB2_H
#define LAB2_H 
#include <iostream>
#include <string>
#include <cstdlib>

using namespace std;

class DollarAmount
{
    double dollar = 0.00;
    double cents = 0.00;
    double avg = 0.00;
    int maxsequence = 0;
    string number;
    public:

        DollarAmount(double num1 = 0, double num2 = 0);

        double getavg() const { return avg; };

        double getDollar() const { return dollar; };

        double getCent() const { return cents; };

        int getmaxsequence() const { return maxsequence; };

        friend istream& operator >> (istream& ins, DollarAmount& arg);

        friend ostream& operator << (ostream& out, const DollarAmount& arg);

        friend DollarAmount operator + (const DollarAmount& arg1, const DollarAmount& arg2);

        friend bool operator > (const DollarAmount& arg1, const DollarAmount& arg2);

        void sortobjects(DollarAmount a[], int length);

        void median(DollarAmount a[], int length);

        //All of the below functions are from lab 1

        void converter1(string array1[], string array2[], string array3[], double m);

        void converter2(double n);

功能:

#include <iostream>
#include <string>
#include <cstdlib>
#include "lab2.h"

using namespace std;


DollarAmount::DollarAmount(double num1, double num2)
{

    dollar = num1;
    cents = num2;

}

istream& operator >> (istream& ins, DollarAmount& arg)
{
    double num1 = 0.00;
    double num2 = 0.00;
    //int num1 = 0;
    //int num2 = 0;
    char ch;
    string s;
    double num3;
    bool wrongInput = false;

   //ins >> num1 >> ch >> num2;
    ins >> num3;
    s = to_string(num3);
    arg.number = s;
    int index = s.find(".");
    num1 = atof(s.substr(0, index).c_str());
    num2 = atof(s.substr(index, 3).c_str()); 

    do
    {
        if (wrongInput == true)
        {
            cout << "Enter the expenditure record (e.g., $1.95, coffee, enter -1 to end):$";
            ins >> num1 >> ch >> num2;
        }

        else if (cin.fail() || num1 < 0 || num1 > 9999 || num2 > 99) //in case the above fails, e.g., ten dollor five cents...
        {
            cout << "Wrong input types. Try again:\n";
            cin.clear(); //clear the error flags in cin 
            cin.ignore(2048, '\n'); //ignore everthing in the input buffer, up to 2048 char, 
            //up to the newline char =< ignore the rest of the line
            wrongInput = true;
        }
        else
            wrongInput = false;
    } while (wrongInput == true || num1 < 0 || num1 > 9999 || num2 > 99); // if input false ask for input again

    arg.dollar = num1;
    arg.cents = num2;
    arg.maxsequence = arg.getmaxsequence() + 1;
    return ins;
}

ostream& operator << (ostream& out, const DollarAmount& arg)
{
    out << arg.getDollar() + arg.getCent();
    return out;
}

DollarAmount operator + (const DollarAmount& arg1, const DollarAmount& arg2)
{
    DollarAmount temp;
    double sum = 0.00;
    double x = 0.00;
    double y = 0.00;
    string z;

    temp.dollar = 0.00;
    temp.cents = 0.00;

    x = arg1.dollar + arg1.cents;

    y = arg2.dollar + arg2.cents;
    sum = x + y;
    cout << "This is the sum: " << sum << endl;

    z = to_string(sum);
    int index = z.find(".");

    temp.dollar = atof(z.substr(0, index).c_str());
    temp.cents = atof(z.substr(index + 1, 2).c_str());
    cout << "This is the dollar: " << temp.getDollar() << endl;
    cout << "This is the cents: " << temp.getCent() << endl;

    return temp;
}

bool operator > (const DollarAmount& arg1, const DollarAmount& arg2)
{
    DollarAmount temp;
    double x, y;

    x = arg1.dollar + arg1.cents;

    y = arg2.dollar + arg2.cents;

    if (x > y)
        return true;
    else
        return false;
}

void DollarAmount::sortobjects(DollarAmount a[], int length)
{
    int i;
    int last = length - 1;  //point to the index of last element in unsorted part of the array 

    for (int pass = 0; pass < length; pass++)
    {
        //a[0]...a[last] is not sorted 
        //repeated bubble the largest element in this range to the end ... 
        for (i = 0; i <= last - 1; i++)
        {
            if (a[i] > a[i + 1])
            {
                //swap 
                DollarAmount tmp;
                tmp = a[i + 1];
                a[i + 1] = a[i];
                a[i] = tmp;
            }
        }
        //at this point, the largest element in a[0...last] is stored in a[last]

        //unsorted part is now a[0...last-1]
        last = last - 1;
    }
}


void DollarAmount::median(DollarAmount a[], int length)
{
    DollarAmount temp;
    int mid;
    double average = 0.00;
    double x = 0.00;
    double y = 0.00;

    if (length % 2 == 0)
    {
        mid = length / 2;
        int test = mid - 1;
        x = a[mid].dollar + a[mid].cents;
        y = a[test].dollar + a[test].cents;
        average = (x + y) / 2.00;
        temp.avg = average;
        cout << temp.getavg();
    }
    else
    {
        mid = length / 2;
        x = a[mid].dollar + a[mid].cents;
        average = x;
        temp.avg = average;
        cout << temp.getavg();
    }

}

void DollarAmount::converter1(string array1[], string array2[], string array3[], double m)
{
    string a;
    string b;
    string c;
    string d;
    int num1 = 0;

    d = to_string(m);
    int index = d.find(".");
    int x = atoi(d.substr(0, index).c_str());

    if (x < 100)
    {

        if (x > 0 && x < 10)
        {
            a = array1[x - 1];
            cout << a;
        }

        else if (x == 10)
        {
            a = array2[0];
            cout << a;
        }

        else if (x > 10 && x < 20)
        {
            a = array2[x - 10];
            cout << a;
        }

        else if (x == 20)
        {
            a = array3[0];
            cout << a;
        }

        else if (x > 20 && x < 30)
        {
            num1 = x - 20;
            b = array3[0];
            a = array1[num1 - 1];
            cout << b << " " << a;
        }

        else if (x == 30)
        {
            a = array3[1];
            cout << a;
        }

        else if (x > 30 && x < 40)
        {
            num1 = x - 30;
            b = array3[1];
            a = array1[num1 - 1];
            cout << b << " " << a;
        }

        else if (x == 40)
        {
            a = array3[2];
            cout << a;
        }

        else if (x > 40 && x < 50)
        {
            num1 = x - 40;
            b = array3[2];
            a = array1[num1 - 1];
            cout << b << " " << a;
        }

        else if (x == 50)
        {
            a = array3[3];
            cout << a;
        }

        else if (x > 50 && x < 60)
        {
            num1 = x - 50;
            b = array3[3];
            a = array1[num1 - 1];
            cout << b << " " << a;
        }

        else if (x == 60)
        {
            a = array3[4];
            cout << a;
        }

        else if (x > 60 && x < 70)
        {
            num1 = x - 60;
            b = array3[4];
            a = array1[num1 - 1];
            cout << b << " " << a;
        }

        else if (x == 70)
        {
            a = array3[5];
            cout << a;
        }

        else if (x > 70 && x < 80)
        {
            num1 = x - 70;
            b = array3[5];
            a = array1[num1 - 1];
            cout << b << " " << a;
        }

        else if (x == 80)
        {
            a = array3[6];
            cout << a;
        }

        else if (x > 80 && x < 90)
        {
            num1 = x - 80;
            b = array3[6];
            a = array1[num1 - 1];
            cout << b << " " << a;
        }

        else if (x == 90)
        {
            a = array3[7];
            cout << a;
        }

        else
        {
            num1 = x - 90;
            b = array3[7];
            a = array1[num1 - 1];
            cout << b << " " << a;
        }
    }

    else if (x < 1000)
    {
        if (x == 100)
        {
            a = array1[0] + " hundred ";
            cout << a;
        }

        else if (x == 200)
        {
            a = array1[1] + " hundred ";
            cout << a;
        }

        else if (x == 300)
        {
            a = array1[2] + " hundred ";
            cout << a;
        }

        else if (x == 400)
        {
            a = array1[3] + " hundred ";
            cout << a;
        }

        else if (x == 500)
        {
            a = array1[4] + " hundred ";
            cout << a;
        }

        else if (x == 600)
        {
            a = array1[5] + " hundred ";
            cout << a;
        }

        else if (x == 700)
        {
            a = array1[6] + " hundred ";
            cout << a;
        }

        else if (x == 800)
        {
            a = array1[7] + " hundred ";
            cout << a;
        }

        else if (x == 900)
        {
            a = array1[8] + " hundred ";
            cout << a;
        }

        else
        {
            // a + "hundred + b + c
            num1 = x / 100;
            a = array1[num1 - 1];
            cout << a << " hundred ";
            converter1(array1, array2, array3, (x % 100));
        }
    }

    else
    {
        if (x == 1000)
        {
            a = array1[0] + " thousand";
            cout << a;
        }

        else if (x == 2000)
        {
            a = array1[1] + " thousand";
            cout << a;
        }

        else if (x == 3000)
        {
            a = array1[2] + " thousand";
            cout << a;
        }

        else if (x == 4000)
        {
            a = array1[3] + " thousand";
            cout << a;
        }

        else if (x == 5000)
        {
            a = array1[4] + " thousand";
            cout << a;
        }

        else if (x == 6000)
        {
            a = array1[5] + " thousand";
            cout << a;
        }

        else if (x == 7000)
        {
            a = array1[6] + " thousand";
            cout << a;
        }

        else if (x == 8000)
        {
            a = array1[7] + " thousand";
            cout << a;
        }

        else if (x == 9000)
        {
            a = array1[8] + " thousand";
            cout << a;
        }

        else
        {
            //a + "thousand" + b + "hundred" + c + d
            num1 = x / 1000;
            a = array1[num1 - 1];
            cout << a << " thousand ";
            converter1(array1, array2, array3, (x % 1000));
        }
    }
}


void DollarAmount::converter2(double n)
{
    cout << n << "/100)" << endl;

}

主要:

#include <iostream>
#include <string>
#include <cstdlib>
#include "lab2.h"

using namespace std;

const int INIT_SIZE = 10;
const int a = 9;
const int b = 10;
const int c = 8;

int main()
{
    string one[a] = { "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };
    string two[b] = { "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen" };
    string three[c] = { "twenty", "thirty", "fourty", "fifty", "sixty", "seventy", "eighty", "ninety" };

    DollarAmount* arr = new DollarAmount[INIT_SIZE];
    DollarAmount* ptr = NULL;
    int avg = 0;
    int arr_size = INIT_SIZE;
    int arr_len = 0; // actual number of objects stored in it , also the index
      // of next free slot in arr

    bool lastInput = false;

    do 
    {
        if (arr_len == arr_size)
        { // the array is full, need to grow! 

           //allocate an array double the cur_size
            ptr = new DollarAmount[arr_size * 2];

            //copy each element in arr into the new array that ptr points to... 
            // Todo: please figure out how to do this...(hint: use a for loop)
            for (int i = 0; i < arr_size; i++)
            {
                ptr[i] = arr[i];
            }

            //now we delete the current arr
            delete[] arr;
            arr = ptr;
            arr_size = arr_size * 2;
        }

        cout << "Enter the expenditure record (e.g., $1.95, coffee, enter 0.0 to end):$";
        cin >> arr[arr_len];  //read in a dollar amount from cin we will allow input such as 0.0

        //If the last read dollar amount is 0.0, then it's the end 
        if (arr[arr_len].getDollar() == 0 && arr[arr_len].getCent() == 0)
            lastInput = true;
        else //we only increment arr_len for input that's not 0.0
            arr_len++;


    } while (lastInput == false);

    DollarAmount total, temp, loopingtotal;


    total = arr[0] + arr[1];
    //cout << "The first total: " << total << endl;
    //cout << "This is sum of first two: " << total;

    //A loopt to add all DollarAmount up, and display the total 

    for (int i = 2; i < arr_len; i++)
    {
        total = total + arr[i];
        cout << "The total for this " << i << " time is: " << total << endl;
    }
    //cout << "This is the sum after loop " << total;

    //Call Sort function to sort the array of DollarAmount 
    temp.sortobjects(arr, arr_len);
    //Display the sorted array, and the median 
    cout << "Sorted list of expenditure:" << endl;
    for (int i = 0; i < arr_len; i++)
    {
        cout << arr[i] << endl;
    }

    //cout << "This is the total cents: " << total.getCent();
    //cout << "This is the total dollar: " << total.getDollar();
    cout << "The total is $" << total.getDollar() << "." << total.getCent();
    cout << " (";
    temp.converter1(one, two, three, total.getDollar());
    cout << " and "; 
    temp.converter2(total.getCent());
    cout << "The median is ";
    temp.median(arr, arr_len);
    cout << "." << endl;
    cout << "Bye!";
    return 0;
}

推荐答案

TL; DR-保持您的类尽可能简单,以充分体现一件事.输入验证可能会很麻烦,因此只需担心您当前的需求即可.在课堂外做所有的数学运算(因为它不相关).

TL;DR - Keep your class as simple as possible to adequately represent one thing well. Input validation can be a rabbit hole, so just worry about your current requirements. Do all your math outside the class (because it's unrelated).

您的工作量超出了需要.首先,您的班级一团糟.一堂课应该有一个单一的目的,对我来说很明显,你没有.

You're working harder than you need to be. First, your class is a mess. A class should have a singular purpose, and it's clear to me that yours does not.

从Money类开始:

class Money {
public:
    Money() = default;
    Money(int d, int c)
        : cents_m(d * 100 + c)
    {
    }
    inline int dollars() const { return cents_m / 100; }
    inline int cents() const { return cents_m % 100; }
    friend std::istream& operator>>(std::istream& sin, Money& obj);
    friend std::ostream& operator<<(std::ostream& sout, const Money& obj);
    friend const Money operator+(const Money& lhs, const Money& rhs);

private:
    int cents_m = 0;
};

忽略所有多余的数学垃圾,它不属于Money类.它属于您需要以功能完成的工作的任何地方.请注意,您现在只存储美分,而不是单独的美元和美分. 5美元等于500便士,这使所有简单的Money数学运算变得更容易.如果您要处理利率和股票交易,那么您会关心几分钱的几分钱,但是我想您不在这里.

Leave out all that extra math garbage, it doesn't belong in a Money class. It belongs wherever you need that kind of work done as functions. Note that instead of separate dollars and cents, you are now storing only cents. $5 is 500 pennies, and this makes all simple Money math a lot easier. If you were dealing with interest rates and stock trades, then you'd care about fractions of pennies, but I'm guessing you don't care here.

由于我已默认初始化cents_m,因此我利用了一些C ++ 11功能,例如默认成员初始化和default来使用默认构造函数.我也在使用初始化部分,您也应该使用.

I'm taking advantage of some C++11 features like Default Member Initialization and defaulting the default constructor now that cents_m is default initialized for me. I'm also using the initialization section, and so should you.

为了展示Money数学的简单性,这是operator+()函数:

To showcase how much easier Money math just got, here's the operator+() function:

const Money operator+(const Money& lhs, const Money& rhs)
{
    int sum = lhs.cents_m + rhs.cents_m;

    return Money(sum / 100, sum % 100);
}

以下是其他运算符:

std::istream& operator>>(std::istream& sin, Money& obj)
{
    std::string tmp;
    std::getline(sin, tmp);
    if (!(tmp.length() > 0)) {
        obj = Money();
        return sin;
    }

    if (tmp[0] == '$') {
        tmp = tmp.substr(1);
    }

    std::size_t location;
    double value = std::stod(tmp, &location);
    if (location != tmp.length()) {
        obj = Money();
    } else {
        int cents = std::lround(value * 100);
        obj = Money(cents / 100, cents % 100);
    }

    return sin;
}

std::ostream& operator<<(std::ostream& sout, const Money& obj)
{
    bool isNegative = obj.cents_m < 0;
    std::string tmp;
    int dollars = abs(obj.cents_m / 100);
    int cents = abs(obj.cents_m % 100);

    if (isNegative) {
        tmp += "(";
    }
    tmp += ("$" + std::to_string(dollars) + ".");
    if (cents < 10) {
        tmp += ("0" + std::to_string(cents));
    } else {
        tmp += std::to_string(obj.cents_m % 100);
    }
    if (isNegative) {
        tmp += ")";
    }

    return sout << tmp;
}

注释:输入流运算符重载可以说明输入了"$"(但仅作为第一个字符),但可能无法说明负数的Money(因为这样做会必须输入$-3.50,而没有人这样做).输入验证不是一件容易的事,您要走多远取决于老师的要求.我承认我的代码很容易在某些无效输入下中断,因为我不想变得很全面(而且我们仍然只谈论ASCII).

NOTES: The input stream operator overload can account for a '$' being entered (but only as the first character), but it likely cannot account for a negative amount of Money (since it would have to be typed $-3.50, and no one does that). Input validation is not simple and how far down that rabbit hole you go depends on what your teacher requires. I will admit that my code will readily break under some invalid inputs because I didn't feel like getting very comprehensive (and we're still only talking about ASCII).

我还选择仅使Money对象将默认值存储在我检测到的一些无效输入上.在运算符重载中带有循环的错误消息是一个坏主意(这不是这些运算符对其他任何事物的行为;过载应按预期运行).要么在后台处理错误,要么抛出异常.这是个案决定,我认为在这种情况下可以静默处理该问题.

I also chose to simply make the Money object store default values on the few invalid inputs I detected. An error message with loops in the operator overload is a bad idea (That's not how these operators behave for anything else; overloads should behave as expected). Either handle the error in the background or throw an exception. This is a case-by-case decision, and I think that silently handling the issue is find in this situation.

如果允许您始终输入有效数字,那么该操作符重载将变得非常简单.

If you are allowed to assume a valid number is always entered, that operator overload gets very simple.

流输出运算符重载至少可以显示负的Money.

The stream output operator overload can at least print negative Money.

这是测试Money类的简短主函数:

Here's a short main function to test the Money class:

int main()
{
    Money one(6, 78);
    Money two(9, 81);
    Money thr(4, 59);

    std::cout << (one + two + thr) << '\n';

    Money fou;
    std::cout << "Give me some money: ";
    std::cin >> fou;
    std::cout << "You only gave me " << fou << "?\n";
}

一些一般性建议:解决编程问题时,您应该做的第一件事是很少编写代码.考虑一下,将其可视化,用自己的语言写出要求,然后考虑如何解决(而不是使用代码,而是需要采取的实际步骤).该代码是一种工具,而不是解决方案.

Some general advice: the first thing you should do when approaching a programming problem is rarely write code. Think on it, visualize it, write out requirements in your own words, and think on how you would solve it (not with code, the actual steps you would need to take). The code is a tool, not the solution.

这篇关于运算符超载问题加法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆