为什么代码在CodeBlocks上不起作用,但在VS上起作用

时间:2019-05-10 10:04:50

标签: c++

此行: “朋友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出错。我该如何解决。

1 个答案:

答案 0 :(得分:3)

cout << ++a1 << endl;//(1)
cout << a2++ << endl;//(2)
cout << a1 * a2 << endl;//(3)
  1. 产生Fraction&,因此它可以绑定到Fraction&const Fraction&,但不能绑定到Fraction&&。允许编译器进行一次隐式的用户定义的转换,因此,最后一次使代码编译的尝试将其转换为double并使用operator<<(ostream&,double&&)operator<<(ostream&,double)不确定是哪个定义的,但输出是一样。
  2. cout << a2++ << endl;产生Fraction,因此它可以绑定到Fraction&&const Fraction&,但不能绑定到Fraction&operator<<(ostream&,Fraction&&)被调用。
  3. 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

不确定 g CodeBlocks 中的tripp 是什么,因为您没有发布错误消息。我猜想您必须启用c ++ 11。