Our second implementation overloads several of the standard operator symbols so that code based on the rational class will be more readable. In particular, we can use the common, infix notation. The previous implementation used prefix notation associated with function calls.
Notice that the operator functions are defined outside of
the class. This means that both operands to operators like +
will be treated in the same way. If we were to define
operator +
as a member function, the left operand
would have to be a rational
, while the right
operand could be an int
or a rational
.
// // Defining the class rational // -- second attempt, using overloaded operators // // by A.B. Maccabe 2/27/97 // #include <iostream.h> class Rational { public: // Constructors Rational( int n = 0, int d = 1 ) { num = n; denom = d; }; // I/O void read( istream &in ) { char slash; in >> num >> slash >> denom; }; void write( ostream &out ) { out << num << '/' << denom; }; // arithmetic Rational neg( ) { return Rational( -num, denom ); }; Rational add( Rational rat ) { return Rational( num*rat.denom + denom*rat.num, denom*rat.denom ); }; Rational sub( Rational rat ) { return add( rat.neg() ); }; Rational mpy( Rational rat ) { return Rational( num*rat.num, denom*rat.denom ); }; Rational div( Rational rat ) { return Rational( num*rat.denom, denom*rat.num ); }; private: int num, denom; }; // define overloaded operators Rational operator +( Rational r1, Rational r2 ) { return r1.add(r2); } ostream & operator <<( ostream &os, Rational r ) { r.write( os ); return os; } istream & operator >>( istream &is, Rational &r ) { r.read( is ); return is; } int main( ) { cout << "Enter a rational (e.g., 12/7):" << flush; Rational r1; cin >> r1; cout << "Enter a second rational:" << flush; Rational r2; cin >> r2; cout << r1 << " + " << r2 << " = " << r1 + r2 << endl; }