用C++编写RationalNumber类

Writing RationalNumber class in C++

本文关键字:RationalNumber 编写 C++      更新时间:2023-10-16

我需要帮助完成一项任务。我对这一切还是个新手。我想去

创建一个具有以下功能的类RatinalNumber(分数):

创建一个构造函数,该构造函数可以防止分数中的0分母,减少或简化非简化形式的分数,并避免负分母。重载此类的加法、减法、乘法和除法运算符。重载此类的关系运算符和相等运算符。

当我把分数加在一起时,我很难让它们适当地减少。例如,如果我的第一个分数是1/3,第二个分数也是1/3,那么答案应该是2/3。然而,每当我运行程序时,无论我放入什么分数,答案都是2/1。

这是我的RatinalNumber头文件:

#pragma once
#include <iostream>
using namespace std;
//RationalNumber class
class RationalNumber
{
public:
    RationalNumber(); //constructor
    ~RationalNumber(); //destructor
    void retrieveInput();
    int GreatestCommonDenom(int num1, int remainder);
    void reduceFraction(int &num, int &denom);
    void operator+(RationalNumber o1);
    void operator-(RationalNumber o1);
    void operator*(RationalNumber o1);
    //void operator/(RationalNumber o1);
private:
    int num, denom;
};

这是我的RatinalNumber函数:

#include "RationalNumber.h"
#include <iostream>
using namespace std;
//RationalNumber Class Functions
RationalNumber::RationalNumber() //constructor
{
    //initializes objects
    num = 1;
    denom = 1;
}
RationalNumber::~RationalNumber() //destructor
{
    //de-allocates memory
} 
void RationalNumber::retrieveInput() //creates user fractions
{
    int num, denom;
    cout << "nEnter a numerator: nn";
    cin >> num;
    cout << "nEnter a denominator: nn";
    cin >> denom;
    cout << endl;
    //denominator
    while (denom == 0)
    {
        cout << "Please enter a denominator: nn";
        cin >> denom;
    }
    while (denom < 0)
    {
        num *= -1;
        denom *= -1;
    }
    cout << num << "/" << denom << endl;
}
int RationalNumber::GreatestCommonDenom(int num1, int remainder) //gets lowest common denominatior
{
    if (remainder == 0)
    {
        return(num1);
    }
    else
    {
        return(GreatestCommonDenom(remainder, num1%remainder));
    }
}
void RationalNumber::reduceFraction(int &num, int &denom) //reduces the fraction to its lowest form
{
    int reduceFrac = 0;
    if (denom > num)
    {
        reduceFrac = GreatestCommonDenom(denom, num);
    }
    else if (denom < num)
    {
    reduceFrac = GreatestCommonDenom(num, denom);
    }
    else
    {
        reduceFrac = GreatestCommonDenom(num, denom);
    }
    num /= reduceFrac;
    denom /= reduceFrac;
    cout << "After reduction, the answer is " << num << "/" << denom << endl;
}
void RationalNumber::operator+(RationalNumber o1) //adds the fractions
{
    RationalNumber temp;
    temp.num = (this -> num * o1.denom) + (o1.num * this -> denom);
    temp.denom = (this -> denom * o1.denom);
    reduceFraction(temp.num, temp.denom);
}
//void operator-(RationalNumber o1)
//{}
//void operator*(RationalNumber o1)
//{}
//void operator/(RationalNumber o1){}

这是我到目前为止的主要程序:

#include <iostream>
#include "RationalNumber.h"
using namespace std;
int main()
{
    cout << "Welcome!n" << endl;
    cout << "Today we shall preform some math functions on fractions.n" << endl;
    //create two objects
    RationalNumber frac1;
    RationalNumber frac2;
    //retrieve user input for their fractions
    cout << "Enter your first fraction: nn";
    frac1.retrieveInput(); 
    cout << "nEnter your second fraction: nn";
    frac2.retrieveInput();
    //using this to see the output (only temporary)
    frac1.operator+(frac2);
    int answer;
    cout << "Menu" << endl;
    cout << "nWhich would you like to preform on your fractions: n" << endl;
    cout << "1: Additionn" << endl;
    cout << "2: Subtractionn" << endl;
    cout << "3: Multiplicationn" << endl;
    cout << "4: Divisionn" << endl;
    cout << "Enter your option: n" << endl;
    cin >> answer;
    return answer;

    switch (answer)
    {
    case 1:
        frac1.operator+(frac2);
        break;
    default:
        cout << "Invalid option." << endl;
    }
    cout << "n" << endl;
    system("pause");
    return 0;
}

为了输出答案,我在开关方面也遇到了一些问题,但它之后几乎关闭了程序,所以我不知道它在输出什么。非常感谢您的帮助!非常感谢。

我会创建一个reduce函数,它总是从构造函数调用:

RationalNumber::RationalNumber(int a, int b)
{
    // do error checking that denominator b is non-zero etc.
    this->a_ = a;
    this->b_ = b;
    reduce(this->a_, this->b_);
}

然后我们所有的操作符(比如add)都会使用构造函数创建一个新的有理数。一个简单的减少函数的例子可以是(修改它以处理负数):

void reduce(int& a, int& b)
{
    int k = 2;
    while(k <= ((a <= b) ? a : b)){
        if(a%k == 0 && b%k == 0){
            a /= k;
            b /= k;
        }
        else
            ++k;
    }   
}

关键是从构造函数调用它,使有理数始终处于其最简化的形式

RationalNumber RationalNumber::add(const RationalNumber& r) const
{
    return RationalNumber(this->a_ * r.b_ + this->b_ * r.a_, this->b_ * r.b_);
}

旁注:如果我是你,我会重载运算符,因此该方法将被称为RatinalNumber RatinalNumber::operator+(Ratinalnumber o1)。这样,当你加上两个有理数时,你可以简单地写

RationalNumber sum = frac1 + frac2

之所以会发生这种情况,是因为您的代码认为它只添加了1/1+1/1,因为这是您在构造函数中设置的。在retrieveInput()中,您的意图是根据用户输入设置分子和分母,但您从未设置类成员变量num和denom。您只设置了在该方法中创建的局部变量,而成员变量的分子和分母仍为1/1。这有道理吗?

您的代码中有几个实例想要更改一些对象,但实际上并没有这样做。

正如Josh所说,retrieveInput函数实际上会更改局部变量num和denom。您有类成员num和denom,但使用语句int num, denom;可以隐藏这些成员变量。

+操作符中,您将添加的结果保存在临时对象中,该对象随后立即被销毁,并且您不返回它。

此外,GreatestCommonDenom函数实际上计算的是最大公约数,而不是最小公约数。

只要多想想你实际上改变了哪些对象,以及这些对象是否是你想要改变的。任何时候在函数中写入type varname;形式的东西(如int num,denom;RationalNumber temp;),一旦函数到达} ,变量varname就会被销毁

还有一件事:从赋值的声音来看,我认为你应该编写一个接受两个参数的构造函数,而不仅仅是在数字创建后输入值。