20
Rational
- #include <iostream>
- #include <cstdlib>
- using namespace std;
- #ifdef DEBUG
- int debug = 0; // 0 - off, 1 - on
- #endif
- #ifdef DEBUG
- #define ONDEBUG( expr ) do { if ( debug ) { expr; } } while ( 0 )
- #else
- #define ONDEBUG( expr )
- #endif
- class Rational {
- friend Rational operator*( const Rational &, const Rational & );
- friend bool operator==( const Rational &, const Rational & );
- friend ostream &operator<<( ostream &ostr, const Rational &r );
- friend istream &operator>>( istream &istr, Rational &r );
- public:
- ~Rational( )
- {
- cout << "DESTRUCTOR\n";
- }
- Rational( int n=0, int d=1 ) : num( n ), den( d )
- {
- cout << "CONSTRUCTOR\n";
- reduce();
- };
- Rational( const Rational &r ) : num( r.num ), den( r.den )
- {
- cout << "COPY\n";
- };
- Rational &operator=( const Rational &r )
- {
- cout << "OPERATOR =\n";
- num = r.num;
- den = r.den;
- return *this;
- };
- Rational &operator*=( const Rational &r )
- {
- cout << "OPERATOR *=\n";
- num *= r.num;
- den *= r.den;
- reduce();
- return *this;
- };
- operator double() const;
- Rational operator++();
- Rational operator++( int );
- int &operator[]( int );
- void print( ) const { cout << num << '/' << den; }
- void printf( ) const { cout << double(num) / double(den); }
- int numerator( ) const { return num; }
- int denominator( ) const { return den; }
- private:
- int num, den;
- int gdc( int x, int y )
- {
- ONDEBUG( cout << "gdc( " << x << ", " << y << " )" << endl; );
- return y == 0 ? x : gdc( y, x%y );
- }
- void reduce( )
- {
- int g = gdc( num, den );
- ONDEBUG( cout << "gdc=" << g << endl; );
- num /= g, den /= g;
- }
- };
- Rational::operator double() const
- {
- return double(num) / double(den);
- }
- Rational Rational::operator++()
- {
- num += den;
- return *this;
- }
- Rational Rational::operator++( int fake )
- {
- Rational t = *this;
- num += den;
- return t;
- }
- int &Rational::operator[]( int i )
- {
- if ( i == 1 )
- return num;
- if ( i == 2 )
- return den;
- cerr << "ERROR: Rational::operator[] - Bad argument";
- exit( 1 );
- }
- Rational operator*( const Rational &x, const Rational &y )
- {
- cout << "OPERATOR *\n";
- Rational z( x.num * y.num, x.den * y.den );
- return z;
- }
- bool operator==( const Rational &x, const Rational &y )
- {
- cout << "OPERATOR ==\n";
- return x.num * y.den == x.den * y.num;
- }
- ostream &operator<<( ostream &ostr, const Rational &r )
- {
- ostr << r.num << "/" << r.den;
- return ostr;
- }
- istream &operator>>( istream &istr, Rational &r )
- {
- cout << "Num? ";
- cin >> r.num;
- cout << "Den? ";
- cin >> r.den;
- r.reduce();
- return istr;
- }
- Rational f( Rational r )
- {
- Rational s = r;
- return s;
- }
- int main()
- {
- Rational x( 21, 66 ); // will be reduced
- Rational y = x;
- {
- Rational x = 4;
- cout << "x=", x.print(), cout << "=", x.printf(), cout << endl;
- }
- cout << "x=", x.print(), cout << "=", x.printf(), cout << endl;
- cout << "y=", y.print(), cout << "=", y.printf(), cout << endl;
- cout << endl;
- cout << "num=" << x.numerator() << endl;
- cout << "den=" << x.denominator() << endl;
- cout << endl;
- {
- const Rational PI( 22, 7 );
- cout << "PI=", PI.print(), cout << "=", PI.printf(), cout << endl;
- x = PI;
- }
- cout << "x=", x.print(), cout << "=", x.printf(), cout << endl;
- cout << endl;
- x = f( y );
- cout << endl;
- {
- Rational x(22, 7);
- Rational y(-3, 8);
- Rational z = x * y; // calls operator =
- cout << "x=", x.print(), cout << endl;
- cout << "y=", y.print(), cout << endl;
- cout << "z=", z.print(), cout << endl;
- cout << endl;
- x *= y;
- cout << "x=" << x << endl; // calls operator <<
- cout << (x == z ? "x=y\n" : "x!=y\n"); // calls operator ==
- }
- cout << endl;
- cin >> x; // calls operator >>
- cout << "x=" << x << endl;
- cout << "x=" << (double)x << endl; // calls operator double()
- cout << "x=" << (double)++x << endl; // calls operator ++
- cout << "x=" << (double)x++ << endl; // calls operator ++
- cout << "x=" << x << endl;
- cout << endl;
- x[ 1 ] = 22; // calls operator []
- x[ 2 ] = 7; // calls operator []
- cout << "x=" << (double)x << endl;
- }
Comments