我真的需要帮助。我有运算符重载的大问题。我为有理数创建了一个名为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;
}
答案 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:抱歉我的英语不好。