I'm currently trying to create a member function that adds an object, Fraction f, to the current object and returns a reference to the current object. my second function is a non-friend helper operator that adds two Fraction objects and returns a copy of the result. I'm not exactly sure how to go about doing this and was looking for some advice. Pretty much the object(s) are just fractions that have been simplified earlier within a previous member function. Essentially all I'm doing is adding simplified fractions. Here's what I have so far:
//header.h
class Fraction {
int num;
int den;
public:
Fraction();
Fraction(int, int);
Fraction& operator+=(const Fraction& f);
friend bool operator==(const Fraction&, const Fraction&);
void simplify();
void display() const;
};
Fraction operator+(const Fraction&, const Fraction&);
and the module:
//module.cpp
#include "Fraction.h"
#include <iostream>
Fraction::Fraction() {
num = 0;
den = 0;
}
Fraction::Fraction(int n, int d) {
num = n;
den = d;
simplify();
}
void Fraction::simplify() {
int temp = den;
int a = num;
int b = den;
int gcd;
if (b > a) {
b = num;
a = den;
}
while (temp != 0) {
temp = a % b;
a = b;
b = temp;
}
gcd = a;
num /= gcd;
den /= gcd;
}
void Fraction::display() const {
std::cout << num << "/" << den << std::endl;
}
//member function in question
Fraction& Fraction::operator+=(const Fraction& f) {
num += f.num;
den += f.den;
return *this;
}
//member function in question
Fraction operator+(const Fraction&, const Fraction&) {
}
EDIT: guess I wasn't as clear previously and that's partly due to the helper function not being revealed. I tried defining the member function and the above code is currently what I have at the moment. I'm not sure if it's logically sound or not as I am still going through the other definitions. the non friend helper operator is the one I am stumped on and do not know what to do. If I can get some help on whether the definition I have for the += member operator is correct and some advice on how to approach the non friend helper operator, that would be great. sorry for any confusion.
since you have the fractions simplified, all you have to do is to use this equation:
and the code will be as follows:
Fraction& Fraction::operator+=(const Fraction& f) {
num = num * f.den + f.num * den;
den *= f.den;
simplify();
return * this;
}
EDIT:
take a look at this question for more about operator overloading
Related
I have a class similar to this:
class Frac
{
int numer;
int denom;
public:
Frac &simplify();
Frac(int &&num, int &&den) : numer { num }, denom { den }
{
simplify();
}
Frac operator*(const int &rhs)
{
Frac result = { numer * rhs, denom };
return result.simplify();
}
}
However, I don't like using the intermediate result when overloading *.
Ideally, I'd like to do something like this:
Frac operator*(const int &rhs)
{
return { numer * rhs, denom }.simplify();
}
but that doesn't work; it constructs an std::initializer_list<int> instead of a Frac and you can't call the member function. In C I would be able to do this with a compound literal but those are not available in standard C++.
How can I generate and return a result in one expression?
Since you are already calling simplify() in the constructor, all you need to call is the constructor by itself, and return the object it creates:
Frac operator*(const int &rhs)
{
return Frac(numer * rhs, denom);
}
If you decide later on to update the constructor to no longer call simplify(), you can still call simplify() explicitly on the object that is created by calling the constructor:
Frac operator*(const int &rhs)
{
return Frac(numer * rhs, denom).simplify();
}
I was practicing something in C++, and I ran into a task which I can solve, but I was curious about this code below. I don't know why we return our values by reference in these two functions:
fraction& operator+=(fraction);
fraction& operator++();
#include <iostream>
using namespace std;
class fraction
{
private:
int br;
int im;
public:
fraction(int=0,int=1);
fraction& operator+=(fraction);
fraction& operator++();
fraction operator++(int);
void print(){cout<<br<<"/"<<im<<endl;}
};
fraction::fraction(int a,int b):br(a),im(b){}
fraction& fraction::operator+=(fraction r)
{
br = br*r.im + im*r.br;
im = im*r.im;
return *this;
}
fraction& fraction::operator++()
{
return (*this)+=1;
}
fraction fraction::operator++(int i)
{
fraction pom(*this);
(*this)+=1;
return pom;
}
int main()
{
cout<<"Type in the values for fractions"<<endl;
int b,i;
cin>>b>>i;
fraction r1(b,i);
cin>>b>>i;
fraction r2(b,i);
r1+=(r2++);
r1.print();
}
Then I tried to remove the & in these functions, and that code also worked fine:
#include <iostream>
using namespace std;
class fraction
{
private:
int br;
int im;
public:
fraction(int=0,int=1);
fraction operator+=(fraction);
fraction operator++();
fraction operator++(int);
void print(){cout<<br<<"/"<<im<<endl;}
};
fraction::fraction(int a,int b):br(a),im(b){}
fraction fraction::operator+=(fraction r)
{
br = br*r.im + im*r.br;
im = im*r.im;
return *this;
}
fraction fraction::operator++()
{
return (*this)+=1;
}
fraction fraction::operator++(int i)
{
fraction pom(*this);
(*this)+=1;
return pom;
}
int main()
{
cout<<"Type in the values for fractions"<<endl;
int b,i;
cin>>b>>i;
fraction r1(b,i);
cin>>b>>i;
fraction r2(b,i);
r1+=(r2++);
r1.print();
}
So, my question is, why do we use & in the first code?
Also, I would appreciate if you could tell me why this code doesn't work. It's a combination of the two codes above, where I removed & only from one function.
#include <iostream>
using namespace std;
class fraction
{
private:
int br;
int im;
public:
fraction(int=0,int=1);
fraction operator+=(fraction);
fraction& operator++();
fraction operator++(int);
void print(){cout<<br<<"/"<<im<<endl;}
};
fraction::fraction(int a,int b):br(a),im(b){}
fraction fraction::operator+=(fraction r)
{
br = br*r.im + im*r.br;
im = im*r.im;
return *this;
}
fraction& fraction::operator++()
{
return (*this)+=1;
}
fraction fraction::operator++(int i)
{
fraction pom(*this);
(*this)+=1;
return pom;
}
int main()
{
cout<<"Type in the values for fractions"<<endl;
int b,i;
cin>>b>>i;
fraction r1(b,i);
cin>>b>>i;
fraction r2(b,i);
r1+=(r2++);
r1.print();
}
Sorry for the noob questions, but I just started practicing in C++, and I spent hours trying to figure this out.
So, my question is, why do we use & in the first code?
& are used for performance and conformance reasons.
Both operators (pre-increment operator ++ and assignment operator+=) from their assumption modify provided value. E.g.:
int i=5;
std::cout << ++i; // This will print 6. Notice there is no more value 5, even here
std::cout << i; // This will print 6 also.
Since the original value is lost, there is no point for creating new object and destroy current one. Just current object can be reused for providing new value.
I would recommend looking into reference when overloading operators, since it is easy to create own version that has performance loss or doesn't work with const objects. Here are some links.
Increment/decrement operators
Assignment operators
Arithmetic operators
Also, I would appreciate if you could tell me why this code doesn't work. It's a combination of the two codes above, where I removed & only from one function.
This one is a little more tricky.
If you take closer look at the code from third example:
fraction fraction::operator+=(fraction r)
{
br = br*r.im + im*r.br;
im = im*r.im;
return *this;
}
fraction& fraction::operator++()
{
return (*this)+=1;
}
You will notice that operator++ is using operator+= inside.
In fact operator++ is returning what operator+= returns, so operator++ is returning reference to local fraction object that is destroyed when operator++ ends. You get reference to just destroyed object. This is bad and this is reason why it doesn't work.
I have two classes Integer and Fraction and one abstract class Number. I am suppose to perform addtion operation by overloading + and also I need to check equality of values using overloading of == operator on these classes.
Operations to be performed
1. Add Integer + Integer = Integer
2. Add Fraction + Fraction = Fraction
3. Add Integer + Fraction = Fraction
I have been able to do 1st and 2nd operation but not able to do addition of integer and fraction.
Below is the code snippet:
Number.h
#pragma once
#include <iostream>
template<class T>
class Number
{
virtual const T operator+ (const T &) = 0;
virtual void display(std::ostream &) const = 0;
virtual bool operator==(const T& rhs) const = 0;
};
Integer.h
#pragma once
#include "Number.h"
#include "Fraction.h"
class Integer : public Number<Integer>
{
int intValue;
public:
void display(std::ostream &) const;
int getValue() const;
void setValue(int);
Integer() {}
Integer(int num);
const Integer operator+ (const Integer &);
virtual ~Integer() {}
bool operator==(const Integer&) const;
};
Integer.cpp
#include "Integer.h"
#include "Number.h"
#include <iostream>
#include <string>
// parameterized constructor
Integer::Integer(int num)
{
intValue = num;
}
// return integer value
int Integer::getValue() const
{
return this->intValue;
}
void Integer::setValue(int x)
{
this->intValue = x;
}
// operator "+" overloading
const Integer Integer::operator+(const Integer &secondNumber)
{
Integer temp = this->intValue + secondNumber.intValue;
return temp;
}
// operator "=" overloading
void Integer::display(std::ostream& stream) const
{
stream << this->intValue;
}
// comparasion operator overload
bool Integer::operator==(const Integer& rhs) const
{
return this->intValue == rhs.intValue;
}
Fraction.h
#pragma once
#include "Number.h"
#include "Integer.h"
class Fraction : public Number<Fraction>
{
Integer _numerator;
Integer _denominator;
public:
void display(std::ostream &) const;
Fraction() = delete;
Fraction(const int &, const int &);
const Fraction operator+ (const Fraction &);
int gcdCalculate(int val1, int val2);
int lcmCalculate(const int val1, const int val2);
virtual ~Fraction() {}
bool operator==(const Fraction& rhs) const;
};
Fraction.cpp
#include "Fraction.h"
#include <iostream>
// parameterised constructor
Fraction::Fraction(const int & num, const int & den)
{
_numerator.setValue(num);
_denominator.setValue(den);
}
// display the fraction value
void Fraction::display(std::ostream & stream) const
{
if (this->_denominator == 0)
std::cout << "Undefined: " << this->_numerator.getValue() << "/" << this->_denominator.getValue() << " (Divide By Zero Exception)";
else
stream << this->_numerator.getValue() << "/" << this->_denominator.getValue();
}
// "+" operator overloading
const Fraction Fraction::operator+(const Fraction &numberTwo)
{
int lcm = lcmCalculate(this->_denominator.getValue(), numberTwo._denominator.getValue());
int multiplier1 = 0;
if (this->_denominator.getValue())
multiplier1 = lcm / this->_denominator.getValue();
int multiplier2 = 0;
if (numberTwo._denominator.getValue())
multiplier2 = lcm / numberTwo._denominator.getValue();
return Fraction((this->_numerator.getValue() * multiplier1) + (numberTwo._numerator.getValue() * multiplier2), lcm);
}
// LCM Calculation
int Fraction::lcmCalculate(const int val1, const int val2)
{
int temp = gcdCalculate(val1, val2);
return temp ? (val1 / temp * val2) : 0;
}
// GCD Calculation
int Fraction::gcdCalculate(int val1, int val2)
{
for (;;)
{
if (val1 == 0) return val2;
val2 %= val1;
if (val2 == 0) return val1;
val1 %= val2;
}
}
// comparision operator overload
bool Fraction::operator==(const Fraction& rhs) const
{
Integer numCheck = this->_numerator;
Integer denCheck = this->_denominator;
if (rhs._numerator.getValue())
numCheck.setValue(numCheck.getValue() / rhs._numerator.getValue());
if (rhs._numerator.getValue())
denCheck.setValue(denCheck.getValue() / rhs._denominator.getValue());
if (numCheck == denCheck) {
return true;
}
return false;
}
QUESTION:
I am confused as how to add Integer + Fraction class.
Do I need to create another class which will inherit from Number class.
How to overload oprator+ present in Number Class.
Suppose I try to add Integer + Fraction = Fraction in the Integer class itself then I will have something like
Example
class Integer : public Number<Integer>
{
const Fraction operator+(const Fraction &);
}
const Fraction Integer::operator+(const Fraction &numberTwo)
{
^^ I will get error here
// Addition opeartion
}
Please help me.
For your first question, the solution is to not use member function overloads, but to create a non-member function overload, e.g.
Fraction operator+(Integer const& integer, Fraction const& fraction)
{
// Logic to add the integer and fraction here
// Perhaps something like...
Fraction f(integer.getValue(), 1); // Create fraction
return f + fraction;
}
The code above uses the Fraction::operator+ function to add the integer.
While you can add an Integer+Fraction operator to your current design like Joachim suggested, that's going to result in some code duplication or at least some unnecessary boilerplate.
I suggest an alternative design instead: Make Integer convertible to Fraction. After all, any integer can be represented by the Fraction type, right?
You can make Integer convertible in two ways: By adding a conversion function to Integer, or by adding a converting constructor to Fraction.
I recommend choosing the converting constructor approach, because Fraction already depends on Integer type and so the cast operator would result in a circular dependency, just like your member operator attempt. I'll leave the implementation as an exercise.
This design requires that the addition operator is implemented as a non-member overload:
Fraction operator+(Fraction const& left, Fraction const& right)
With the converting constructor, this function can handle any combination of (F + F), (F + I) and (I + F).
I defined a Fraction class as following, overloading the "=" & "+" operators.
I made this program as simple as possible to show the problem.
#include <iostream>
class Fraction {
private:
int nominator;
int denominator;
public:
Fraction ();
Fraction (int, int);
Fraction & operator = (Fraction &);
friend Fraction operator + (Fraction &, Fraction &);
// static function:
// find the Greatest Common Divisor of two numbers
int static GCD(int x, int y);
};
int Fraction::GCD(int x, int y) {
if (y == 0) {
return x;
} else {
return GCD (y, x % y);
}
}
Fraction::Fraction () {
nominator = NULL;
denominator = NULL;
}
Fraction::Fraction (int num_1, int num_2) {
int divisor = Fraction::GCD (num_1, num_2);
nominator = num_1 / divisor;
denominator = num_2 / divisor;
}
Fraction & Fraction::operator = (Fraction &A) {
nominator = A.nominator;
denominator = A.denominator;
return *this;
}
Fraction operator + (Fraction &A, Fraction &B) {
int nominator = A.nominator * B.denominator + B.nominator * A.denominator;
int denominator = A.denominator * B.denominator;
int divisor = Fraction::GCD (nominator, denominator);
return Fraction (nominator / divisor, denominator / divisor);
}
And in the Main() function, I have three test case
int main(int argc, const char * argv[]) {
Fraction frac_a = Fraction(1, 3);
Fraction frac_b = Fraction(1, 4);
// test 1: no compile error
frac_a + frac_b;
frac_a = frac_b;
// test 2: no compile error
Fraction frac_c = frac_a + frac_b;
// test 3: Error: No viable overloaded '='
Fraction frac_d;
frac_d = frac_a + frac_b;
return 0;
}
The question is, why "test 3" has "No viable overloaded '='" error?
Your assignment operator is declared to take a reference to a non-const Fraction. Your addition operator returns by-value, so you are trying to assign a temporary to frac_c. Temporaries can not bind to non-const references.
The fix is to make your assignment operator take by const-reference:
Fraction & operator = (const Fraction &);
That's because your operator= can't bind to temporaries.
You should define it like this:
Fraction & Fraction::operator = (const Fraction &A)
so, it will bind to temporaries and constant objects and literals.
You defined the assignment operator= to take an lvalue reference as argument, but tried to pass it a temporary. Temporaries only bind to const references or rvalue references.
You should read up on how to overload operators in a usable way, e.g. the same problem occurs with the nonconst lvalue references accepted by your operator+.
That means, use Fraction& operator=(Fraction const&) and Fraction operator+(Fraction const&, Fraction const&).
I'm doing a Little rational class for my Project and I overload all aritmethic operators. Well, when I try to overload operator= I have a Little and now I don't know if is my problem (i don't know how it Works) or problem of my wroten code (i wrote it bad) here's the code:
class rational{
public:
double& operator=(double& d){
d= this->num/this->den;
return d;
}
double& operator=(rational& r){
double d= r.num/r.den;
return d;
}
double& operator=(){
double d= this->num/this->den;
return d;
}
}
Ok, what's wrong? what's right? (i think that all is wrong haha)
My goal is do that:
int main(){
rational r(4, 5);
double d= r;
}
Can I do it? if yes, how?
You don't want an assignment operator for this purpose - you should instead overload a conversion operator; e.g.
class rational {
private:
int num;
int den;
public:
// ...
operator double() { return double(num) / double(den); }
};
This will allow
rational r(4, 5);
double d = double(r); // d = 0.8
The assignment operators should be used for changing the state of an existing object, if that's something you want to allow. You probably would not want to allow assignment of a double to a rational there is no unambiguous meaning for such an operation. However, you might want to provide helpers for assigning an int, say, in addition to the usual one for assigning another rational:
rational &operator=(const rational &rhs)
{
num = rhs.num;
den = rhs.den;
return *this;
}
rational &operator=(int rhs)
{
num = rhs;
den = 1;
return *this;
}
Here I think a user-defined conversion operator would be more appropriate.
class rational {
public:
rational( int iNum, int iDen ) : num( iNum ), den( iDen ) {}
// ...
operator double() { return (double)num / (double)den; }
private:
int num;
int den;
};
int main()
{
rational r( 1, 2 );
double n = r;
std::cout << r << std::endl; // output 0.5
return 0;
}
Here is a little live example to illustrate this : http://ideone.com/I0Oj66
About the copy assignment operator= :
A copy assignment operator of class T is a non-template non-static member function with the name operator= that takes exactly one parameter of type T.
The operator= is used to change an existing object.
You can use it for example to copy the state of another object :
rational &operator=( const rational &rhs )
{
num = rhs.num;
den = rhs.den;
return *this;
}