I need help getting my function to overload the + operator to add a integer and a Rational object. Right now I am able to add two rational objects with my overloaded + function but not and integer and an object. I'm not really sure how to go about doing it. Would i need to change the overloaded + function to test weather two objects are being added or an object and an int. Is there someway to check what the type of a value is so i can use an if statement. If someone could help me out I would appreciate it. An example of what i would like my program to do is..

//SETUP FIXTURE
int lhs(3);
Rational rhs(2);
Rational result;

//TEST
result = lhs + rhs;

My code for my program so far is below.

#include <iostream>
#include <string>
#include <cmath>

using namespace std;

class Rational{
   public:
	  int num;
	  int den;
	  bool neg;

  
	  Rational(int n, int d); // contructor for rationals
	  Rational(int n); // contructor for reals
	  Rational();//default constructor
	  
	  int get_num();
	  int get_denom();
	  int gcd();
	  void simplify();
	  bool is_negative();
	  Rational operator +(Rational);
	  Rational operator -(Rational);
	  Rational operator *(Rational);
	  Rational operator /(Rational);
	  Rational &operator +=(Rational &);
	  Rational operator -=(Rational);
	  Rational& operator /=(Rational&);
	  Rational& operator *=(Rational&);
	  Rational operator ++(int);
	  Rational operator ++();
   
	  

};



int main(){
	Rational result, a, rat(1,2), rat2(3,2), rat3(5,2), rat4(3,2);
	
	//result.den = a.get_denom();
	//result.num = a.get_num();
	//result.neg = a.is_negative();

	//cout << result.num << "/" << result.den << endl;
	//cout << result.neg << endl;
	
	//cout << "rat3 before: " << rat3.num << "/" << rat3.den << endl;
	//cout << "rat4 before: " << rat4.num << "/" << rat4.den << endl;
	//cout << rat3++ << endl;
	//cout << rat3;
	
	
	//cout << "rat3 after: " << rat3.num << "/" << rat3.den << endl;
	//cout << "rat4 after: " << rat4.num << "/" << rat4.den << endl;
	
}


Rational::Rational(int n, int d)
{
	if(n == 0)
	{
		num = n;
		den = 1;
	}else
	{
		num = n;
		den = d;
	}
}
Rational::Rational(int n)
{
	num = n;
	den = 1;
}
Rational::Rational()
{
	num = 0;
	den = 1;
}
int Rational::get_num()
{
	simplify();
	return abs(num);
	
}
int Rational::get_denom()
{
	simplify();
	return abs(den);
	
}
int Rational::gcd()
{	int a = num;
	int b = den;
	int temp;
	
	while(b != 0)
	{
	    temp = b;
		b = a % b;
		a = temp;
	}
	return a;
}
void Rational::simplify()
{
	int gcdNum = gcd();

	if(gcdNum != 0)
	{
		num = num / gcdNum;

		den = den / gcdNum;
	}

	
}
bool Rational::is_negative()
{
	
	    if(num < 0||den < 0)
		    neg = true;
	    else
		    neg = false;
 
	
	 return neg;
}

Rational Rational:: operator +(Rational ratPassed)
{
	Rational ratResult;
	ratResult.num = num * ratPassed.den + den * ratPassed.num;
	ratResult.den = den * ratPassed.den;

	return ratResult;


}
Rational Rational:: operator -(Rational ratPassed)
{
	Rational ratResult;
	ratResult.num = num * ratPassed.den - den * ratPassed.num;
	ratResult.den = den * ratPassed.den;

	return ratResult;
}
Rational Rational:: operator *(Rational ratPassed)
{
	Rational ratResult;
	ratResult.num = num * ratPassed.num;
	ratResult.den = den * ratPassed.den;

	return ratResult;
}
Rational Rational:: operator /(Rational ratPassed)
{
	Rational ratResult;
	ratResult.num = num * ratPassed.den;
	ratResult.den = den * ratPassed.num;

	return ratResult;
}
Rational& Rational::operator *=(Rational &m)
{
	num *= m.num;
	den *= m.den;
	return *this;
}
Rational& Rational::operator +=(Rational &m)
{
	num = num * m.den + m.num * den;
	den *= m.den;
	return *this;
}
Rational& Rational::operator /=(Rational &m)
{
	num *= m.den;
	den *= m.num;
	return *this;
}
Rational Rational:: operator ++(int unused)
{
	Rational temp = *this;

	num += den;

	return temp;
}
Rational Rational:: operator ++()
{
	num += den;

	return *this;
}

Do you want the overload to be part of your Rational class or a global function? It makes a huge difference in how you declare it, how you implement it, and how you write the statement(s) that attempt to use it.

On a side note:

Rational operator +(Rational);

This is a very inefficient, and dangerous, way of declaring/writing the method, and it will only work for 2 Rational objects. A more efficient, and safer, way would be:

const Rational operator +(const Rational &) const;

All of your operators exhibit these same problems.

Edited 5 Years Ago by Fbody: n/a

I'd like it to be part of my Rational class unless making it a global function would be a better way of doing it. I always thought making things global was a bad practice or so I've been told. Maybe I'm wrong.

Making non-const variables global is generally considered "bad parctice", but it's not a big deal with functions. In fact, unless you put your functions in a class, you can't do it any other way.

If you want the operator to be a part of your Rational class, you will have to write it with a const int & argument and always write it in client code as Rational + int. Because of how operators work with an instance of a class, reversing the order will not work. I almost think you would be better off writing it as 2 global functions with 1 version calling the other:

//prototypes:
Rational operator+ (const int &, const Rational &);          //version 1, integer first
Rational operator+ (const Rational &, const int &);          //version 2, Rational first

//call
resultRational = someRational + someInt;                     //calls version 2

//implementation
Rational operator+ (const int &lhs, const Rational &rhs) {   //implement version 1
  //implementation
}

Rational operator+ (const Rational &lhs, const int &rhs) {   //implement version 2
  return (int + Rational);                                   //call version 1 and return result
}
This article has been dead for over six months. Start a new discussion instead.