I am working with fraction classes in a book, I have run into a problem I cant seem to get around, I was going to read through and skip the examples, but it appears the last few chapters all deal with this class.
The idea is getting operators to work on a subclass, which according to the book, the goal is to provide constructors for converting items back and forth.
The main class if Fraction, and the subclass is FloatFraction. Fraction is constructed from integers as numerator and denominator, and it has functions for handle operator user for +,-,*,/.
Now I want to be able to use the operators on float fractions, which are constructed as either 2 integers, or a double.
When constructed with a double of say 1.34, it would produce a fraction of 134/100.
I know from previous chapters dealing with just the Fraction class that the operators all work as expected.
Something is wrong with the example code and I can't seem to figure it out, it's been a couple of hours and I haven't been successful.
Heres the code for the two classes, The Fraction class is modified from the book to add *, and / operators. But I am posting the FloatFraction class directly from the source cd.
Code:
#include <iostream>
using namespace std;
class Fraction
{
private:
int num, den; //numerator and denominator
public:
void set(int n, int d)
{
num = n;
den = d;
normalize();
}
int get_num()
{
return num;
}
int get_den()
{
return den;
}
Fraction()
{
set(0, 1);
}
Fraction(int n, int d)
{
num = n;
den = d;
normalize();
}
Fraction(int n)
{
set(n, 1);
}
Fraction(Fraction const &src)
{
num = src.num;
den = src.den;
}
Fraction add(const Fraction &other);
Fraction mult(const Fraction &other);
Fraction div(const Fraction &other);
Fraction sub(const Fraction &other);
bool operator>(const Fraction &other);
bool operator<(const Fraction &other);
bool operator==(const Fraction &other)
{
return(num == other.num && den == other.den);
}
Fraction operator+=(const Fraction &fract)
{
return add(fract);
}
Fraction operator+(const Fraction &fract)
{
return add(fract);
}
Fraction operator*(const Fraction &fract)
{
return mult(fract);
}
Fraction operator/(const Fraction &fract)
{
return div(fract);
}
Fraction operator-(const Fraction &fract)
{
return sub(fract);
}
friend ostream &operator<<(ostream &os, Fraction &fr);
//friend ostream &operator>>(ostream &os, Fraction &fr);
private:
void normalize(); //put fraction into standard form
int gcf(int a, int b);
int lcm(int a, int b);
};
#include <iostream>
#include <stdlib.h>
using namespace std;
ostream &operator<<(ostream &os, Fraction &fr)
{
os << "(" << fr.num << "/" << fr.den << ")";
return os;
}
bool Fraction::operator>(const Fraction &other)
{
if(num * other.den > den * other.num)
{
return 1;
}
else
{
return 0;
}
}
bool Fraction::operator<(const Fraction &other)
{
if(num * other.den < den * other.num)
{
return 1;
}
else
{
return 0;
}
}
Fraction Fraction::div(const Fraction &other)
{
Fraction f1, f2, f3;
f1.set(num, den);
f2.set(other.den, other.num);
f3 = f1.mult(f2);
f3.set(f3.den, f3.num);
return f3;
}
Fraction Fraction::sub(const Fraction &other)
{
Fraction f1, f2, f3;
f1.set(num, den);
f2.set(other.num * -1, other.den);
f3 = f1.add(f2);
f3.set(f3.num * -1, f3.den);
return f3;
}
Fraction Fraction::add(const Fraction &other)
{
Fraction fract;
int lcd = lcm(den, other.den);
int quot1 = lcd / den;
int quot2 = lcd / other.den;
fract.set(num * quot1 + other.num * quot2, lcd);
return fract;
}
Fraction Fraction::mult(const Fraction &other)
{
Fraction fract;
fract.set(num * other.num, den * other.den);
return fract;
}
int Fraction::gcf(int a, int b)
{
if(a % b == 0)
{
return abs(b);
}
else
{
return gcf(b, a % b);
}
}
int Fraction::lcm(int a, int b)
{
return (a / gcf(a, b)) * b;
}
void Fraction::normalize()
{
//handle cases involving 0
if(den == 0 || num == 0)
{
num - 0;
den = 1;
}
//put negative sign in numerator only
if(den < 0)
{
num *= -1;
den *= -1;
}
//factor out gcf from numerator and denominator
int n = gcf(num, den);
num /= n;
den /= n;
}
FloatFraction class
Code:
#include <iostream>
#include "Fract.h"
using namespace std;
class FloatFraction : public Fraction {
public:
FloatFraction() {set(0, 1);}
FloatFraction(int n, int d) {set(n, d);}
FloatFraction(int n) {set(n, 1);}
FloatFraction(const FloatFraction &src)
{set(src.get_num(), src.get_den());}
FloatFraction(const Fraction &src)
{set(src.get_num(), src.get_den());}
double get_float() {
return static_cast<double>(get_num())/get_den();}
};
int main() {
FloatFraction f1(1, 2), f2(1, 3), f3;
f3 = f1 + f2;
cout << "Value of f3 is " << f3 << endl;
cout << "Float value of f3 is " << f3.get_float() << endl;
// TEST THE == OPERATOR
if (f3 == FloatFraction(5, 6))
cout << "1/2 + 1/3 is equal to 5/6." << endl;
return 0;
}
I put the problem pieces of code in bold.
The errors I am getting are:
Floatfract1\main.cpp|103|error: passing 'const FloatFraction' as 'this' argument of 'int Fraction::get_num()' discards qualifiers|
Like I said this is copied exactly from the book.
I am not looking for an answer. I am just getting very frustrated. My understanding of these bolded lines of code is this:
const means the value doesn't changes, the Fraction/FloatFraction is the type, and &src is a reference to some other object.
Either a Fraction or a floatfraction, the code then should take this reference and use the items it has to set a new item.
if its const FloatFraction &src it produces a FloatFraction, and if its const Fraction &src, it produces a Fraction.
or is the purpose of
Code:
FloatFraction(const FloatFraction &src)
{set(src.get_num(), src.get_den());}
to provide a copy constructor, and the purpose of
Code:
FloatFraction(const Fraction &src)
{set(src.get_num(), src.get_den());}
to change the item to a Fraction?
Maybe I don't exactly understand it correctly.
The third subclass where I am running into problems is:
Code:
class ProperFraction : public FloatFraction
{
public:
ProperFraction()
{
set(0, 1);
}
ProperFraction(int n)
{
set(n, 1);
}
ProperFraction(int n, int d)
{
set(n, d);
}
ProperFraction(const ProperFraction &src)
{
Fraction::set(src.Fraction::get_num, src.get_den);
}
ProperFraction(const FloatFraction &src)
{
set(src.Fraction::get_num, src.get_den);
}
ProperFraction(const Fraction &src)
{
set(src.Fraction::get_num, src.get_den);
}
void pr_proper(ostream &os);
int get_whole();
int get_num(); //overridden function
};
I once again put the problem lines in bold, if I leave the const I get this error message:
Floatfract1\main.cpp|155|error: no matching function for call to 'ProperFraction::set(<unresolved overloaded function type>, <unresolved overloaded function type>)'|
Floatfract1\fract.h|12|note: candidates are: void Fraction::set(int, int)|
If I change the bolded lines to be
Code:
Fraction::set(src.Fraction::get_num, src.get_den);
I receive the same error.
If I remove the const it still produces the same error.
Sorry about such a huge post, I was kind of hoping I'd figure it out as I went through whats going on but no luck. I am tempted to skip all this and move past getting the examples to work and just reading what the book says.