算数重载为Rational数

时间:2016-06-04 00:05:06

标签: c++ operator-overloading

我真的需要帮助。我有运算符重载的大问题。我为有理数创建了一个名为Rational的数据类型,它们是可以表示为比率a / b的数字,其中a和b都是整数,b!= 0。 a通常称为分子,b称为分母。我想要一个应该有两个有理数相加,相减,相乘,除以和比较的方法的类。这是我试图使用的代码。

我的问题是如何通过从main发送数字来进行运算符重载,例如相互求和?在我的代码中唯一可行的是重载<<操作

#include <iostream>

using namespace std;

class Rational
{
protected:
    int a;
    int b;
public:
    Rational::Rational()
    {
        a = 0;
        b = 0;
    }
    Rational::Rational(int first, int second)
    {
        a = first;
        b = second;
    }
    friend ostream &operator << (ostream &os, Rational &p)
    {
        os << p.a << p.b; //prints 3 and 9 that i giving in main
        return os;
    }
    Rational Rational::operator + (Rational &s)
    {
        a = a + s.b;  // here i will sum     a + b
        return *this;
    }

    Rational Rational::operator += (int b)
    {
        a += b;   //here i want sum     a + b
        return *this;
    }
    Rational Rational::operator -= (int b)
    {
        a = a - b; // here i want subtracting    a - b
        return *this;
    }
    Rational Rational::operator *(int b)
    {
        a = a * b;   //here i want multiply     a * b
        return *this;
    }
    Rational Rational::operator /(int b)
    {
        a = a / b;   //here i want multiply     a * b
        return *this;
    }

    bool Rational::operator==(const Rational &r) const
    {
        if (a != r.b)  // here i want add requred methods for comparison of two rational numbers.
            return false;
        else
            return true;
    }
};

int main()
{

    Rational r1 (3, 9);
    cout << r1;

    Rational r2(4, 5);
    cout << r2;


    cout << endl;
    system("pause");

    return 0;
}

1 个答案:

答案 0 :(得分:1)

你很好;只是微小的调整。

最重要的是你必须避免类定义中名称的<class name>::部分;因此,当您在类中内联定义构造函数时,正确的版本为Rational ()而不是Rational::Rational ()

其他调整/建议,无特定顺序。

1)在理性数字中,你应该避免零分母的情况;因此b的默认大小写应为1,而不是零

2)你应该添加一个检查,以确保b下一个构造和一些修改操作不是零;我建议使用像

这样的私有方法
void check()
 { if ( b == 0 ) throw std::runtime_error("rational with zero den"); }

3)我建议你尽可能使用构造函数初始化列表;所以你的构造函数应该是

  Rational () : a(0), b(1)
   { }  // no need for check(), in this case

  Rational (int first, int second) : a(first), b(second)
   { check(); }

4)您可以看到一个整数,如有理数,1为分母;这对于操作员管理非常非常有用(我们稍后会看到它);使用参数的默认值,您可以在单个构造函数中统一构造函数

  Rational (int first = 0, int second = 1) : a(first), b(second)
   { check(); }

适用于以下情况

  Rational r1;        // 0/1 
  Rational r2(7);     // 7/1
  Rational r3(5, 2);  // 5/2

5)您定义赋值运算符使用危险名称输入值;例如,在

  Rational operator += (int b)
   {
     a += b;   //here i want sum     a + b
     return *this;
   }

输入int值为b作为分母;危险的;你应该以不同的方式重命名它,这样你就可以使用分母(参见下面的观点)

6)您的+=运算符错误:应该是

  Rational operator += (int i)
   {
     a += i * b;  //  a/b + i = (a + i*b) / b
     return *this;
   }

-=

相同的问题

7)作业运算符应返回Rational &而不是Rational;所以你可以写像

这样的东西
  a = b += 5;

8)你也应该为Rational编写赋值运算符;

之类的东西
  Rational & operator += (const Rational & r)
   {
     a *= r.b;
     a += r.a * b;
     b *= r.b;
     return *this;
   }

9)使用默认构造函数和Rational & operator += (const Rational & r),您可以删除Rational & operator += (int i);这是因为如果你写

  Rational  r;
  r += 7;

7在理性对象7/1中自动转换(第二个参数默认为1的构造函数);然后,调用Rational & operator += (const Rational & r);您可以出于性能原因维护int版本,但编写了大量不必要的代码

10)我强烈建议您定义非赋值运算符(==!=>>=<,{{1 }},<=+-*)作为/函数而不是类的方法;例如,friend可能是

operator==

通过这种方式,当整数值位于 friend bool operator== (const Rational & r1, const Rational & r2) { return (r1.a * r2.b) == (r2.a * r1.b); } 的左侧或右侧时,您也可以针对整数检查Rational运算符(感谢默认构造函数);我的意思是,对于== friend,以下两个测试都在运行

==

以[{1}}为方法,第二个 Rational r(4,2); if ( r == 2 ) if ( 2 == r ) 无法正常工作

显然,只有一些建议可以启动。

p.s:抱歉我的英语不好。