#include <iostream.h>
class Rational {
friend ostream & operator << (ostream & , Rational ); // Note 1
friend Rational operator+(long, Rational); // long + rational
public:
Rational(long = 0, long = 1); // Constructor with parms
Rational(const Rational &); // Copy Constructor - Note 2
Rational operator=(Rational); // assignment operation
Rational operator+(Rational); // rational + rational
Rational operator+(long); // rational + long
bool operator==(Rational);
private:
long num;
long denom;
};
// constructor with parameters
Rational::Rational(long a, long b) {
num = a;
denom = b;
if(denom < 0) { num *= -1; denom *= -1;} // keep minus in numerator
}
// copy constructor
Rational::Rational(const Rational &A) {
num = A.num;
denom = A.denom;
cout << "copy constructor called" << endl;
}
// rational = rational
Rational Rational::operator=(Rational B) {
num = B.num;
denom = B.denom;
return *this;
}
// rational + rational
Rational Rational::operator+(Rational B) {
Rational temp(0,1);
temp.num = B.denom * num + denom * B.num;
temp.denom = denom * B.denom;
if(temp.denom < 0) { temp.num *= -1; temp.denom *= -1; } // keep minus in numerator
return temp;
}
// rational + long
Rational Rational::operator+(long B) {
Rational temp(0,1);
temp.num = denom * B + num;
temp.denom = denom;
if(temp.denom < 0) { temp.num *= -1; temp.denom *= -1; } // keep minus in numerator
return temp;
}
// rational == rational
bool Rational::operator==(Rational B) {
if(num == B.num && denom == B.denom) return true;
else return false;
}
// *************** the friend functions *****************************
// long + rational
Rational operator+(long B, Rational A) {
Rational temp(0,1);
temp.num = A.denom * B + A.num;
temp.denom = A.denom;
if(temp.denom < 0) { temp.num *= -1; temp.denom *= -1; } // keep minus in numerator
return temp;
}
ostream & operator << (ostream & os, Rational A) {
os << A.num << "/" << A.denom;
return os; // enables cascading
}
// *************** main *****************************
int main() {
Rational X(0,0), Y(1,2), Z(3,4), Q;
int i;
cout << Q << endl;
X = Y;
cout << X << endl;
X = Z + (long)1;
cout << X << endl;
X = (long)1 + Z;
cout << X << endl;
if(Y == Z) cout << "Y == Z" << endl;
else cout << "Y != Z" << endl;
cin >> i;
return 0;
}
copy constructor called 0/1 copy constructor called copy constructor called copy constructor called 1/2 copy constructor called copy constructor called copy constructor called copy constructor called 7/4 copy constructor called copy constructor called copy constructor called copy constructor called copy constructor called 7/4 copy constructor called Y != Z
The Notes:
source code
0 - note that this example does not include the reduction to simpliest form.
1 - the << operator must be a friend function since is accesses private data elements.
2 - a copy constructor is called whenever an object is needed as in a call-by-value argument, returning a object
by value or initializing an object to be a copy of another object, as in:
Rational X(1,2);
Rational Y = X;
It's always a good practice to include a copy constructor since it will eliminate obscure errors when passing
arguments by reference, etc.