为什么它会给重载运算符带来错误? [英] Why it gives an error about overloaded operators?
问题描述
编写一个类Fraction,通过重载这些操作的标准运算符来定义加法,减法,乘法和
除以分数。写
a函数成员减少因子和过载I / O操作符输入和
输出分数
< pre lang =c ++> #include < < span class =code-leadattribute> iostream >
class 分数
{
int m_n1,m_n2,m_d1,m_d2,m_n,m_d;
public :
Fraction():m_n1( 0 ),m_n2(< span class =code-digit> 0 ),m_d1( 0 ),m_d2( 0 )
{
}
分数( int n1, int n2, int d1, int d2):m_n1(n1),m_n2(n2 ),m_d1(d1),m_d2(d2)
{
fractionsAddition(n1,n2,d1,d2);
reduce(m_n,m_d);
}
int gcd( int n, int d);
int lcm( int d1, int d2);
void fractionsAddition( int n1, int n2, int d1, int d2);
void reduce( int n, int d);
朋友 std :: ostream& operator<<(std :: ostream& out, const 分数& f);
朋友 std :: istream& operator>>(std :: istream& in, const Fraction& f);
};
int Fraction :: gcd( int n,< span class =code-keyword> int d)
{
if (d == 0 )
{
return n;
}
return gcd(d,n%d);
}
int Fraction :: lcm( int d1, int d2)
{
int max =(d1> d2)? d1:d2;
执行
{
if ((max%d1 == 0 )&&(max%d2 == 0 ))
{
返回 max;
}
else
{
++ max;
}
}
while (max< d1 * d2);
return d1 * d2;
}
void Fraction :: reduce( int n, int d)
{
int g = gcd(m_n,m_d);
m_n = m_n / g;
g = g / m_d;
}
void Fraction :: fractionsAddition( int n1, int n2, int d1, int d2 )
{
// return(n1 * lcm(d1,d2)+ n2 * lcm (d1,d2))/ lcm(d1,d2);
std :: cout<<(n1 * lcm(d1,d2)+ n2 * lcm(d1,d2))< < /<<< lcm(d1,d2);
}
std :: istream& operator>>(std :: istream& in, const 分数& f)
{
in>> f.m_n1>> f.m_n2>> f.m_d1>> f.m_d2;
返回 ;
}
std :: ostream& operator<<(std :: ostream& out, const 分数& f)
{
out<< f.m_n1<< /<<< f.m_d1<< +<< f.m_n2< ;< /<< f.m_d2;
返回 out;
}
int main()
{
Fraction f( 1 , 4 , 5 , 6 跨度>);
std :: cout<< f;
}
我的尝试:
我在谷歌上搜索过,但我找不到好的回复这段代码非常低效:
int Fraction :: lcm( int d1 , int d2)
{
int max =(d1> d2)? d1:d2;
执行
{
if ((max%d1 == 0 )&&(max%d2 == 0 ))
{
返回 max;
}
else
{
++ max;
}
}
while (max< d1 * d2);
return d1 * d2;
}
使用公式会更聪明
lcm(d1,d2)= d1 * d2 / gcd(d1, d2)
[更新]
使用GCD的尾递归效率也不高。循环是首选解决方案,因为它需要更少的资源,因此更快。
请注意,大多数编译器将尾递归转换为循环。
尾巴调用 - 维基百科 [ ^ ]
您正在将一个常量Fraction引用传递给istream运算符,这会使所有整数值保持不变。没有istream运算符在右侧采用'const int'。
从声明和istream运算符的定义中删除const,如下所示。
std :: istream& operator>>(std :: istream& in,Fraction& f)
Write a class Fraction that defines adding, subtracting, multiplying, and
dividing fractions by overloading standard operators for these operations. Write
a function member for reducing factors and overload I/O operators to input and
output fractions
#include <iostream>
class Fraction
{
int m_n1, m_n2, m_d1, m_d2, m_n, m_d;
public:
Fraction():m_n1(0), m_n2(0), m_d1(0), m_d2(0)
{
}
Fraction(int n1, int n2, int d1, int d2):m_n1(n1), m_n2(n2), m_d1(d1), m_d2(d2)
{
fractionsAddition(n1, n2, d1, d2);
reduce(m_n, m_d);
}
int gcd(int n, int d);
int lcm(int d1, int d2);
void fractionsAddition(int n1, int n2, int d1, int d2);
void reduce(int n, int d);
friend std::ostream &operator<<(std::ostream &out, const Fraction &f);
friend std::istream &operator>>(std::istream &in, const Fraction &f);
};
int Fraction::gcd(int n, int d)
{
if(d==0)
{
return n;
}
return gcd(d, n%d);
}
int Fraction::lcm(int d1, int d2)
{
int max=(d1>d2) ? d1: d2;
do
{
if((max%d1==0) && (max%d2==0))
{
return max;
}
else
{
++max;
}
}
while(max<d1*d2);
return d1*d2;
}
void Fraction::reduce(int n, int d)
{
int g=gcd(m_n, m_d);
m_n=m_n/g;
g=g/m_d;
}
void Fraction::fractionsAddition(int n1, int n2, int d1, int d2)
{
//return (n1*lcm(d1, d2)+n2*lcm(d1, d2))/lcm(d1, d2);
std::cout<<(n1*lcm(d1, d2)+n2*lcm(d1, d2))<<"/"<<lcm(d1,d2);
}
std::istream &operator>>(std::istream &in, const Fraction &f)
{
in>>f.m_n1>>f.m_n2>>f.m_d1>>f.m_d2;
return in;
}
std::ostream &operator<<(std::ostream &out, const Fraction &f)
{
out<<f.m_n1<<"/"<<f.m_d1<<"+"<<f.m_n2<<"/"<<f.m_d2;
return out;
}
int main()
{
Fraction f(1,4,5,6);
std::cout<<f;
}
What I have tried:
I have searched on Google, but I couldn't find a good response
This code is highly inefficient:
int Fraction::lcm(int d1, int d2) { int max=(d1>d2) ? d1: d2; do { if((max%d1==0) && (max%d2==0)) { return max; } else { ++max; } } while(max<d1*d2); return d1*d2; }
would be smarter to use the formula
lcm(d1 , d2) = d1 * d2 / gcd(d1 , d2)
[Update]
Using the tail recursion for the GCD is not efficient either. A loop is a preferred solution because it need less resources and thus is faster.
Note that most compilers transform the tail recursion to a loop.
Tail call - Wikipedia[^]
You are passing a constant Fraction reference to the istream operator, which makes all the integer values constant. There is no istream operator that takes a 'const int' on the right-hand side.
Remove the const from the declaration and definition of the istream operator as shown below.
std::istream &operator>>(std::istream &in, Fraction &f)
这篇关于为什么它会给重载运算符带来错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!