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.
Related
I'm trying to write a class handling multiplication, division, etc of polynomials.
In my header file, I have my class definition, in which I have those public functions :
void Poly_Mult(const Polynomial& Poly);
void Poly_Divide(const Polynomial& Poly);
and also two friend functions :
friend Polynomial Poly_Mult(const Polynomial& Poly1, const Polynomial& Poly2);
friend Polynomial Poly_Divide(const Polynomial& Poly1, const Polynomial& Poly2);
I have defined both Poly_Mult functions with no problem and I try to use them to define the Poly_Divide ones.
For the friend function, I have no problem. However, in the member function :
bool Polynomial::Poly_Divide(const Polynomial& Poly)
{
if (Poly.m_Degree == 0)
return false;
Polynomial result;
result.m_Degree = this->m_Degree - Poly.m_Degree;
result.m_Variable = this->m_Variable;
Polynomial reduced(*this);
double GuidingFactor = Poly.m_Terms[Poly.size() - 1].Factor();
while (reduced.m_Degree >= Poly.m_Degree)
{
int exp = reduced.m_Degree - Poly.m_Degree;
double termFactor = reduced.m_Terms[reduced.size() - 1].Factor() / GuidingFactor;
//I get an error on this next line. The compiler doesn't seem to find to right overloaded function for Poly_Mult
reduced.Poly_Subtract(Poly_Mult(Poly, Polynomial(termFactor, Poly.m_Variable, exp)));
result.m_Terms.push_back(VarPower(termFactor, exp));
reduced.Simplify();
}
result.Simplify();
*this = result;
if(reduced.size() == 1 && reduced.m_Terms[0].Factor() == 0 && reduced.m_Terms[0].Exponent() == 0)
return true;
else
return false;
}
The code is functionally the same in the friend function and it works perfectly as intended, no errors.
instead of the whole detailed function since the friend function works fine, but again, the compiler doesn't seem to find to right overloaded function.
I really don't see the problem here, as the functions have different parameters so I see no ambiguity.
By simplifying the code, I get the same problem with this :
in my header file, I have my class definition :
class Polynomial
{
private:
int m_Degree;
public:
Polynomial(int degree)
: m_Degree(degree) {};
Polynomial(const Polynomial& Poly)
: m_Degree(Poly.m_Degree) {};
Polynomial& operator=(const Polynomial& Poly)
{
m_Degree = Poly.m_Degree;
}
void Multiply(const int& number);
friend Polynomial Multiply(const Polynomial& Object, const int& number);
void Divide(const int& number);
friend Polynomial Divide(const Polynomial& Object, const int& number);
};
Then, in my cpp file, I have the implementation of the functions :
#include "Polynomial.h"
void Polynomial::Multiply(const int& number)
{
m_Degree *= number;
}
Polynomial Multiply(const Polynomial& Object, const int& number)
{
return Polynomial(Object.m_Degree * number);
}
void Polynomial::Divide(const int& number)
{
Polynomial copy = *this;
Polynomial result = Multiply(copy, (1./number)); //This is where the problem is. The compiler doesn't find the right overloaded function
*this = result;
}
Polynomial Divide(const Polynomial& Object, const int& number)
{
Polynomial result = Multiply(Object, (1. / number));
return result;
}
I get those errors :
error C2660: 'Polynomial::Multiply': function does not take 2 arguments
no suitable constructor exists to convert from "void" to "Polynomial"
Class fraction
{
public:
fraction operator+ (const fraction& fr) const;
private:
int num; //numerator
int den; //denominator
};
I wanted to overlaod the operator+ so that it perfoms the multiplication of an integer constant (calling object) and a fraction.
fraction fraction::operator+ (const fraction& fr) const
{
fraction result;
result.num = fr.num + fr.den * (*this);
//error message says invalid operands to binary exprssion ('int' and 'constant fraction')
result.den = fr.den;
simplified_fr(result); // a helper function to simplify the resulted fraction
return result;
}
It seems that the problem is about the type of calling object. I intended to make it a constant integer but the computer thought it was a 'const fraction'. Can someone please advise me why this happened and how can I fix it? Thank you in advance!!!
I assume you would like to do achieve something like this:
fraction fract;
fraction fract2 = 2 + fract;
The answer is that you cannot overload member method operator+ for non-class objects. BUT you can define/overload global operator+ function:
fraction operator+(int num, const fraction& rFrac)
{
//your implementation
}
You will probably need access to private members of fraction class. That can be acomplished by making operator+ a friend:
class fraction
{
//...
friend fraction operator+(int num, const fraction& rFrac);
//...
}
My Header file:
#include <iostream>
using namespace std;
class Fraction
{
private:
double numerator;
double denominator;
public:
Fraction();
~Fraction();
Fraction(const Fraction& c);
Fraction(double,double);
//setter
void setNumerator(double newnumerator);
void setDenominator(double newdenominator);
//getter
double getNumerator();
double getDenominator();
//friend overlaoding operators
friend ostream& operator<<(ostream& os, Fraction f);
};
My CPP file:
#include <iostream>
#include "Fraction.h"
using namespace std;
Fraction::Fraction()
{
cout<<"Empty constructor called"<<endl;
}
Fraction::~Fraction()
{
cout<<"Deconstructor called"<<endl;
}
Fraction::Fraction(const Fraction& c)
{
c.numerator = numerator;
c.denominator = denominator;
}
Fraction::Fraction(double newnumerator, double newdenominator)
{
numerator = newnumerator;
denominator = newdenominator;
}
void Fraction::setNumerator(double newnumerator)
{
numerator = newnumerator;
}
void Fraction::setDenominator(double newdenominator)
{
denominator = newdenominator;
}
double Fraction::getNumerator()
{
return numerator;
}
double Fraction::getDenominator()
{
return denominator;
}
ostream& operator<<(ostream& os, Fraction f)
{
os<<f.numerator<<"/"<<f.denominator<<endl;
return os;
}
My testcpp.file:
#include <iostream>
#include "Fraction.h"
using namespace std;
int main()
{
Fraction f1;
cout<<f1;
return 0;
}
When I run this code I get bellow error message:
Fraction.cpp: In copy constructor ‘Fraction::Fraction(const Fraction&)’:
Fraction.cpp:20:17: error: assignment of member ‘Fraction::numerator’ in read-only object
c.numerator = numerator;
Fraction.cpp:21:19: error: assignment of member ‘Fraction::denominator’ in read-only object
c.denominator = denominator;
PS: Once I left out the copy copy constructor and tried if the rest really works, but I get the same error message for the overloading operator(cin >>).
Thank you very much.
Your copy constructor is backwards. You're supposed to copy FROM the parameterized instance to the this instance.
Fraction::Fraction(const Fraction& c)
{
numerator = c.numerator;
denominator = c.denominator;
}
get rid of the const and put a ref. &symbol next to Fraction. why? to make changes on the object ?
friend istream& operator>>(istream &is, Fraction &f);
istream& operator>>(istream &is, Fraction &)
{
cout<<"Enter numerator"<<endl;
is>>f.numerator;
cout<<"Enter denominator"<<endl;
is>>f.denominator;
return is;
}
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'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