此行: “朋友ostream&运算符<<(ostream&os,Fraction && obj)” 它可以在Visual Studio上运行,但不能在CodeBlocks上运行。 并且错误是“ <&>标记前的预期的','或'...'| ”
#include <iostream>
#include <cstdio>
using namespace std;
int lcf(int n, int m)
{
if (n < m)
{
int tmp = n;
n = m;
m = tmp;
}
if (n % m == 0)
return m;
else
return lcf(m, n % m);
}
class Fraction
{
private:
int fenzi, fenmu;
public:
Fraction(int a, int b) :fenzi(a), fenmu(b) {}
Fraction operator+(Fraction& another)
{
fenzi += another.fenzi;
fenmu += another.fenmu;
return *this;
}
Fraction operator*(Fraction& another)
{
fenzi *= another.fenzi;
fenmu *= another.fenmu;
return *this;
}
operator double()
{
return 1.0* fenzi / fenmu;
}
friend istream& operator>>(istream& is, Fraction& obj)
{
is >> obj.fenzi;
getchar();
is >> obj.fenmu;
return is;
}
friend ostream& operator<<(ostream& os, Fraction&& obj)
{
int t = lcf(obj.fenzi, obj.fenmu);
obj.fenzi /= t;
obj.fenmu /= t;
os << obj.fenzi << "/" << obj.fenmu;
return os;
}
Fraction& operator++()
{
fenzi++;
fenmu++;
return *this;
}
Fraction operator++(int)
{
Fraction tmp(fenzi, fenmu);
fenzi++;
fenmu++;
return tmp;
}
};
int main()
{
Fraction a1(9, 11), a2(1, 2);
cout << double(a2) << endl;
cout << ++a1 << endl;
cout << a2++ << endl;
cout << a1 * a2 << endl;
return 0;
}
如果代码是: “ 朋友ostream&运算符<<(ostream&os,Fraction&obj)” 在主函数中,“ cout << a1 * a2 << endl ”会奇怪地调用“ operator double()”函数,而不是“ friend ostream&operator <<( )”。 因此,我添加了“&”(Fraction && obj),并按预期成功在Visual Studio上工作。但是CodeBlocks出错。我该如何解决。
答案 0 :(得分:3)
cout << ++a1 << endl;//(1)
cout << a2++ << endl;//(2)
cout << a1 * a2 << endl;//(3)
Fraction&
,因此它可以绑定到Fraction&
或const Fraction&
,但不能绑定到Fraction&&
。允许编译器进行一次隐式的用户定义的转换,因此,最后一次使代码编译的尝试将其转换为double
并使用operator<<(ostream&,double&&)
或operator<<(ostream&,double)
不确定是哪个定义的,但输出是一样。cout << a2++ << endl;
产生Fraction
,因此它可以绑定到Fraction&&
或const Fraction&
,但不能绑定到Fraction&
。 operator<<(ostream&,Fraction&&)
被调用。cout << a1 * a2 << endl;
产生的Fraction
与以前一样。您应该几乎永远不要有副作用的印刷品。当然不是修改您传递的对象的对象。然后有人会编写这样的代码,可怜的灵魂将花费不必要的时间在调试器上:
Fraction a;
Fraction b = a;
if(debug_build)
cout <<"LOG:"<<a<<'\n';
assert(a==b);
我的解决方法是:
friend ostream& operator<<(ostream& os, const Fraction& obj)
{
int t = lcf(obj.fenzi, obj.fenmu);
os << obj.fenzi/t << "/" << obj.fenmu/t;
return os;
}
一切都可以绑定到const Fraction&
,它应该是const
。 (1),(2),(3)将起作用,并且不会调用double()
。我什至会考虑使double()
明确,因为它将禁止这些让您感到困惑的意外呼叫。除非您有充分的理由不这样做,否则可能无法进行一些额外的输入。
最后一件事是真正鼓励您保持const正确,而不要制作不必要的副本。
Fraction& operator+(const Fraction& another)
Fraction& operator+(const Fraction& another)
Fraction operator++(int) const
不确定您必须启用c ++ 11。 g CodeBlocks 中的tripp 是什么,因为您没有发布错误消息。我猜想