I didn't realize there was a class working with fraction classes until just today...
Mathematically, a fraction is composed of an integer numerator and an integer denominator. You should
not have a constructor of the form
Fraction( float f )
(unless, of course, your professor wants otherwise... but it is still a bad idea).
If you must perform conversions from
float to
Fraction via assignment and the like, then use an
explicit constructor like
jsmith indicated... this will prevent the compiler from taking too many liberties when it shouldn't. (Remember, a
fraction is not a
float.) Converting a float to a fraction is not a particularly simple thing to do. (But it can be done, mind you.)
Hopefully you have a constructor something like:
Fraction( int numerator = 0, int denominator = 1 )
This gives you a default constructor, an int to Fraction constructor, and a proper fraction constructor.
I/O operators
(In C++, that's the
extraction and
insertion operators.)
The purpose of the operator is to allow you to read or write your data to
any stream -- the same one given as argument (in your case, that's
is and
os -- BTW, a word like "is" is not a good name for a variable; I tend to use unambiguous names like "ins" and "outs" for in-stream and out-stream respectively).
However, your operators not only completely ignore the argument streams, but they invoke
other streams to perform their task. Worse than that -- the input operator (the 'extract from stream' operator) performs
output. That's bad.
The I/O operators should expect input based upon a specific format. For example, you may say that a fraction, when written, must always have the form:
['-'] digits '/' digits
This makes I/O easy -- in fact, it is the natural way we write fractions. Your program might then run:
Enter a fraction: -2/5
You entered -2/5 which is the same as -0.4.
The extraction (input) operator should read the "-2/5" directly. It should
not expose the user to the details of how the class is implemented ("Yoinks! That is a numerator and a denominator in there!")
Doing input is typically a bit more difficult than output. You will need to do some error checking on the "/" character of the input. I recommend you use
peek() and
setstate(). For example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
istream& operator >> ( istream& ins, Fraction& frac )
{
// stuff to read the numerator goes here
...
// read the "/" and complain if it isn't
int c = ins.peek();
if (c != '/')
{
ins.setstate( ios::failbit );
return ins;
}
// stuff to read the denominator goes here
...
// return the current stream for the next input operator
return ins;
}
|
Notice how
cin and
cout are not involved anywhere inside the extraction operator function. The code that uses the extraction operator does stuff like:
1 2 3
|
Fraction f;
cout << "Please enter a fraction: " << flush;
cin >> f;
|
Output is considerably easier. Just check to make sure your denominator isn't negative before writing things out. You will have to think about how to turn a fraction like:
3
---
-4
into something that prints like "-3/4". Remember, your insertion (output) operator should not modify the object:
ostream& operator << ( ostream& outs, const Fraction& frac )
Well, lunch is calling, so that's all I'm going to say for now.
You might want to point other confused classmates to this post.
Hope this helps.