Reputation: 83
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
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