# Inheritance problems

• 12-30-2010
bob887
Inheritance problems
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);`

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.
• 12-31-2010
nimitzhunter
The problem is that both get_num() and get_den() are not const, so they could modify the "src" object. So when you use "const A & src", and then call on Fraction::get_num() and Fraction::get_den(), the compiler does not know the purposes of these two functions. But, since "src" cannot be modified, but these two function allows modification ( no const declaration), hence your compiler will throw a compiling error. To fixed that problem, just do:
Code:

```int get_num() const {return num;} int get_den() const {return den;}```
By the way, i think it's better to use the constructor and copy constructor to initialize member variables than using the 'set' function.
• 12-31-2010
bob887
Awesome thanks a lot for helping out, the Inheritance confuses me a little but I think I am starting to pick it up.
• 01-01-2011
Elysia
This isn't an inheritance issue, though. This is a basic const issue. A const function may not call a non-const function (the guarantee of const would be lost since the non-const function could modify the object).