• (2 Pages)
• 1
• 2

## 15 Replies - 1554 Views - Last Post: 04 September 2011 - 12:22 AMRate Topic: //<![CDATA[ rating = new ipb.rating( 'topic_rate_', { url: 'http://www.dreamincode.net/forums/index.php?app=forums&module=ajax&section=topics&do=rateTopic&t=245870&amp;s=d8c3ef4c2c55b5c9c03a8edaf430b694&md5check=' + ipb.vars['secure_hash'], cur_rating: 0, rated: 0, allow_rate: 0, multi_rate: 1, show_rate_text: true } ); //]]>

### #1 hulla

• Writing Lines

Reputation: 49
• Posts: 733
• Joined: 05-March 11

Posted 03 September 2011 - 01:41 AM

This code from LearnCpp.com shows operator overloading in action but I cannot create my own operator.

Here is my code . . .

```class Fraction
{
double m_dNumerator, m_dDenominator; // Private by default
public:
double value() { return m_dNumerator/m_dDenominator; }
Fraction()
{
m_dNumerator = 1;
m_dDenominator = 0;
}
friend Fraction operator*(Fraction Fraction1, Fraction Fraction2);
Fraction(double dNumerator, double denominator)
{
m_dNumerator = dNumerator;
assert(denominator != 0);
m_dDenominator = denominator;
}
};

Fraction operator*(Fraction& Fraction1, Fraction& Fraction2)
{
return Fraction(Fraction1.m_dNumerator*Fraction2.m_dNumerator, Fraction1.m_dDenominator*Fraction2.m_dDenominator);
}

int main()
{
Fraction pi(22, 7);
Fraction phi(161, 100);
Fraction sum = pi*phi;
cout << sum << endl;
return 0;
}

```

There are too many compiler errors
so I'll include the first five . . .

Quote

|50|error: 'double Fraction::m_dNumerator' is private|
|50|error: 'double Fraction::m_dDenominator' is private|
|76|error: no match for call to '(Fraction) (int, int)'|
|76|error: no match for call to '(Fraction) (int, int)'|
|77|error: no match for 'operator<<' in 'std::cout << sum'|

This post has been edited by hulla: 03 September 2011 - 01:45 AM

Is This A Good Question/Topic? 0

### #2 hulla

• Writing Lines

Reputation: 49
• Posts: 733
• Joined: 05-March 11

Posted 03 September 2011 - 01:53 AM

Oh wait there are only 4 errors and the rest are notes.
Hold on I've updated my code a bit by putting .0 on the end of the values for the Fraction pi and Fraction phi . . .

```class Fraction
{
double m_dNumerator, m_dDenominator; // Private by default
public:
double value() { return m_dNumerator/m_dDenominator; }
Fraction()
{
m_dNumerator = 1;
m_dDenominator = 0;
}
friend Fraction operator*(Fraction Fraction1, Fraction Fraction2);
Fraction(double dNumerator, double denominator)
{
m_dNumerator = dNumerator;
assert(denominator != 0);
m_dDenominator = denominator;
}
};

Fraction operator*(Fraction& Fraction1, Fraction& Fraction2)
{
return Fraction(Fraction1.m_dNumerator * Fraction2.m_dNumerator, Fraction1.m_dDenominator * Fraction2.m_dDenominator);
}

int main()
{
Fraction pi(22.0, 7.0);
Fraction phi(161.0, 100.0);
Fraction sum = pi*phi;
cout << sum << endl;
return 0;
}

```

Errors:

Quote

|50|error: 'double Fraction::m_dNumerator' is private|
|50|error: 'double Fraction::m_dDenominator' is private|
|76|error: ambiguous overload for 'operator*' in 'pi * phi'|
|77|error: no match for 'operator<<' in 'std::cout << sum'|

### #3 Karel-Lodewijk

Reputation: 454
• Posts: 864
• Joined: 17-March 11

Posted 03 September 2011 - 02:41 AM

Also to be able to use cout with your custom class, you have to overload the << operator for ostream, like this.

```ostream& operator<<(ostream& out, const Fraction& fraction)
{
return out << fraction.m_dNumerator << "/" << fraction.m_dDenominator;
}

```

And this needs access to your private data members, so you need to invite another friend to the party.

```friend ostream& operator<<(ostream& out, const Fraction& fraction);

```

This post has been edited by Karel-Lodewijk: 03 September 2011 - 02:54 AM

### #4 hulla

• Writing Lines

Reputation: 49
• Posts: 733
• Joined: 05-March 11

Posted 03 September 2011 - 03:14 AM

Oh thanks alot there's only one error left now . . .

Here's my code . . .

```class Fraction
{
double m_dNumerator, m_dDenominator; // Private by default
public:
double value() { return m_dNumerator/m_dDenominator; }
Fraction()
{
m_dNumerator = 0;
m_dDenominator = 1;
}
friend Fraction operator*(Fraction& Fraction1, Fraction& Fraction2);
Fraction(double dNumerator, double denominator)
{
m_dNumerator = dNumerator;
assert(denominator != 0);
m_dDenominator = denominator;
}
};

Fraction operator*(Fraction& Fraction1, Fraction& Fraction2)
{
return Fraction(Fraction1.m_dNumerator * Fraction2.m_dNumerator, Fraction1.m_dDenominator * Fraction2.m_dDenominator);
}

int main()
{
Fraction pi(22.0, 7.0);
Fraction phi(161.0, 100.0);
Fraction sum = pi*phi;
cout << sum << endl;
return 0;
}

```

Error . . .

Quote

|77|error: no match for 'operator<<' in 'std::cout << sum'|

This post has been edited by hulla: 03 September 2011 - 05:08 AM

### #5 mi14chal

Reputation: 81
• Posts: 202
• Joined: 11-December 10

Posted 03 September 2011 - 04:54 AM

Did you carefully read what Karel-Lodewijk wrote? He wrote:

Quote

you have to overload the << operator for ostream, like this.

and he gave you example of this operator.

### #6 hulla

• Writing Lines

Reputation: 49
• Posts: 733
• Joined: 05-March 11

Posted 03 September 2011 - 04:58 AM

### #7 baavgai

• Dreaming Coder

Reputation: 6385
• Posts: 13,637
• Joined: 16-October 07

Posted 03 September 2011 - 06:38 AM

```class Fraction {
private: // yes, it's implicit.  always be explicit
// the m_d thing when out with the 80s
// read what the inventor of C++ has to say about hungarian notation
// and move on
// double m_dNumerator, m_dDenominator;
double numerator, denominator;
// should these really be double?
public:
// group your constructors... somehow, i like top

// constructor notation, also good
Fraction() : numerator(0), denominator(1) { }

Fraction(double n, double d) : numerator(n), denominator (d) {
// and what, throw an error?
// assert(denominator != 0);
// or perhaps deal with invalid input gracefully
numerator = 0; denominator = 1;
}

// const correctness is good
double value() const { return numerator/denominator; }

// why?
// friend Fraction operator*(Fraction& Fraction1, Fraction& Fraction2);
// you can do the same thing, more cleanly, with no friend, as
Fraction operator* (const Fraction&) const;

// you might want a couple more getters here...
};

```

### #8 hulla

• Writing Lines

Reputation: 49
• Posts: 733
• Joined: 05-March 11

Posted 03 September 2011 - 07:25 AM

I haven't learned about the notation stuff (you mentioned in the code) yet. Yeah I know it's a crappy excuse but I'm still learning.

What's wrong with the member vars being double? I find it convenient for fractions that have non-integers as their numerator or denominator.

Thanks for line 28. I didn't think about doing that.

### #9 KYA

• yay verily

Reputation: 3155
• Posts: 19,200
• Joined: 14-September 07

Posted 03 September 2011 - 08:30 AM

I think the point baavgai is making is that you never ever ever see: 5.8/6.8. Anywhere.

Fractions are usually (I'm sure there's an edge case somewhere) composed of integers: 2/3, 5/8, etc...

### #10 baavgai

• Dreaming Coder

Reputation: 6385
• Posts: 13,637
• Joined: 16-October 07

Posted 03 September 2011 - 02:56 PM

KYA, on 03 September 2011 - 11:30 AM, said:

I think the point baavgai is making is that you never ever ever see: 5.8/6.8. Anywhere.

Bingo!

There are fraction and decimals, not fractions with decimals. It's simply a different paradigm. Now, you might want something like Fraction(double). Then, if you really wanted, you could do:
```Fraction f(Fraction(5.8) /  Fraction(6.8));

```

If I were to do a Fraction class, and you made me think it might be fun, I'd do something like:
```class Fraction {
private:
long numerator, denominator;
void reduce();
public:
Fraction();
Fraction(long numerator, long denominator);
Fraction(double);

long getNumerator() const;
long getDenominator() const;
double toDouble() const;

Fraction operator+ (const Fraction&) const;
Fraction operator+ (long) const;
Fraction operator+ (double) const;

Fraction operator- (const Fraction&) const;
Fraction operator- (long) const;
Fraction operator- (double) const;

Fraction operator* (const Fraction&) const;
Fraction operator* (long) const;
Fraction operator* (double) const;

Fraction operator/ (const Fraction&) const;
Fraction operator/ (long) const;
Fraction operator/ (double) const;

void print(ostream &) const;
};

```

This post has been edited by baavgai: 03 September 2011 - 02:57 PM

### #11 PlasticineGuy

• mov dword[esp+eax],0

Reputation: 281
• Posts: 1,436
• Joined: 03-January 10

Posted 03 September 2011 - 08:54 PM

Note that fractional notation with decimals where a fraction is used to mean division, but it does not actually represent a fraction.

### #12 hulla

• Writing Lines

Reputation: 49
• Posts: 733
• Joined: 05-March 11

Posted 03 September 2011 - 10:14 PM

I'd rather keep them doubles because I like to pretend I'm professional and act like I'm going to release my program so I wouldn't like inputs possible being truncated.

Also some of my math homework questions involve non-int numerators/denominators that need to be converted to decimal form so yeah.

It feels pro to write a program to help me with my math homework

This post has been edited by hulla: 03 September 2011 - 10:15 PM

### #13 PlasticineGuy

• mov dword[esp+eax],0

Reputation: 281
• Posts: 1,436
• Joined: 03-January 10

Posted 03 September 2011 - 10:54 PM

Quote

I'd rather keep them doubles because I like to pretend I'm professional and act like I'm going to release my program so I wouldn't like inputs possible being truncated.
Fractions with decimals make no logical or mathematical sense.

Quote

Also some of my math homework questions involve non-int numerators/denominators that need to be converted to decimal form so yeah
Read what I posted. They're not fractions, merely an algebraic representation of division that goes handily with the fractional notation.
e.g. Let's say that we have the "fraction" 1.5/3. This is equivalent to 1/2. If you could have decimals in your numerators/denominators, then you could simplify any fraction infinitely. Example:
```4/8 = 2/4 = 1/2 = 0.5/1 = 0.25/0.5 = 0.125/0.25 = ...
```

### #14 hulla

• Writing Lines

Reputation: 49
• Posts: 733
• Joined: 05-March 11

Posted 03 September 2011 - 11:14 PM

I know. In (maths) class and for my (maths) homework I only use fractional notation for my division so I know exactly what you mean.

The only way my fraction class can simplify is by making the denominator 1 (dividing the numerator by the denominator) (ie making the fraction in decimal form).

That's why I want it to have non-int numerators and denominators because it can help with my algebraic homework while I'm solving the questions.

I'm planning on editing my constructor to have the numerator and denominator multiply by 2 until they are both whole and then simplify but I still want the program to accept the input of the numerator and denominator without truncating them to integers.

### #15 PlasticineGuy

• mov dword[esp+eax],0

Reputation: 281
• Posts: 1,436
• Joined: 03-January 10

Posted 03 September 2011 - 11:34 PM

Your algorithm won't work. Consider 1.1:
```1.1 x 2 = 2.2
2.2 x 2 = 4.4
4.4 x 2 = 8.8
8.8 x 2 = 17.6
17.6 x 2 = 35.2
35.2 x 2 = 70.4
...
```
As you can see, the number will never be whole.