user7476499
user7476499

Reputation: 83

Why I add an "&" ,it outputs different?

I've asked a similar question before (Why the code doesn't work on CodeBlocks,but on VS works).
Now a new error confused me.

cout << ++a1 << endl; will call the function operator double().

If in the code Fraction& operator++() I remove the & to make it Fraction operator++(), it will call the ostream& operator<<(ostream& os, Fraction&& obj).

#include <iostream>
using namespace std;
class Fraction
{
private:
    int fenzi, fenmu;
public:
    Fraction(int a, int b) :fenzi(a), fenmu(b) {}
    operator double()
    {
        return 1.0* fenzi / fenmu;
    }
    friend ostream& operator<<(ostream& os,  Fraction&& obj)
    {
        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 << a1++ << endl;
    return 0;
}

I wonder why is the output different?

Fraction operator++() and Fraction& operator++(), the former returns a copied one, and the latter returns the original one. But their types are both Fraction. I think it should have both called ostream& operator<<(ostream& os, Fraction&& obj).

Fraction operator++() output(I expected):

0.5
10/12
10/12

Fraction& operator++() output:

0.5
0.833333
10/12

Upvotes: 1

Views: 208

Answers (1)

Tarick Welling
Tarick Welling

Reputation: 3255

operator double()
{
    return 1.0* fenzi / fenmu;
}

Is the implicit conversion operator. Adding the explicit keyword to the operator double() will help with this because the compiler won't implicitly convert a Fraction into a double without you explicitly casting it into a double. The addition would look like:

explicit operator double()
{
    return 1.0* fenzi / fenmu;
}

The correct output stream operator is defined as
friend ostream& operator<<(ostream& os, Fraction& obj).
You defined it as
friend ostream& operator<<(ostream& os, Fraction&& obj)

Fraction&& is a rvalue reference instead of a lvalue reference (Fraction&). The compiler used the implicit conversion operator because the operator++ (in either definition) returns a lvalue (reference) instead of a rvalue reference which was defined as the parameter of the output stream operator.

Upvotes: 1

Related Questions