Help with assigning fractions to a class template constructor

Hey guys,

I'm really stuck on my programming assignment. I'm almost done but I cannot seem to get this last final part down. The part I'm stuck on is creating a new class template <Fraction> and getting fraction numbers into the constructor so I can output them to the console and use the fraction values to compute the area and perimeter to calculate width and length for my program. When I am able to pass in regular numbers I have no problem. However, I have no idea how to pass in fraction values. Any help would be greatly appreciated!

Fraction.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#ifndef Fraction_h
#define Fraction_h

//#include <iostream>

struct Fraction
{
  int numerator;
  int denominator;

};

Fraction operator+ (const Fraction&, const Fraction&);
Fraction operator* (const Fraction&, const Fraction&);
bool operator> (const Fraction&, const Fraction&);
Fraction operator* (const Fraction, const int x);
Fraction operator* (const int y, const Fraction&);

#endif  


Fraction.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>

#include "Fraction.h"
using namespace std; // needed for void Fraction::returnFraction() const

// addition
Fraction operator+ (const Fraction& a, const Fraction& b)
{
  Fraction brandNew;
  brandNew.numerator = a.numerator + b.numerator;
  brandNew.denominator = a.denominator + b.denominator;
  return brandNew;
}

// multiplication
Fraction operator* (const Fraction& a, const Fraction& b)
{
  Fraction brandNew;
  brandNew.numerator = a.numerator * b.numerator;
  brandNew.denominator = a.denominator * b.denominator;
  return brandNew;
}

// comparing if first is bigger than second
bool operator> (const Fraction& a, const Fraction& b)
{
  if(a.numerator > b.numerator)
    return true; return false;
}

// fraction as first operand and integer as second operand which produce fraction result
Fraction operator* (const Fraction& a, const int x)
{
  Fraction brandNew;
  brandNew.numerator = a.numerator * (x);
  brandNew.denominator = a.denominator * (1);  
  return brandNew;
}

// integer as first operand and fraction as second operand which produce fraction result
Fraction operator* (const int y, const Fraction& a)
{
  Fraction brandNew;
  brandNew.numerator = a.numerator * (y);
  brandNew.denominator = a.denominator * (1);
  return brandNew;
}


Rectangle.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#ifndef Rectangle_h
#define Rectangle_h

#include <iostream>
using namespace std;

template <class DataType>

class Rectangle
{
public:
  
  Rectangle(){} // pass in no parameters and does nothing

  
  Rectangle (DataType a, DataType b) // pass in length and width of rectangle
  {
    length = a;
    width = b;
  }
  
  void setLength(float length);
  DataType getLength() const {return length;}

  void setWidth(float width);
  DataType getWidth() const {return width;}
  
  bool compareSides (const float& length, const float& width) const
  {
   if (length > width)
     return true; return false;
  }
  
  void computePerimeter(const float& length, const float& width);
  float getPerimeter() const {return perimeter;}
  void computeArea(const float& length, const float& width);
  float getArea() const {return area;}
  
  
private:
  float side;
  DataType length;
  DataType width;
  float perimeter;
  float area;
};


// set length
template <class DataType>


void Rectangle<DataType>::setLength(float length)
{
  //length = length*2;
}

 


// set width
template <class DataType>
void Rectangle<DataType>::setWidth(float width)
{
  width = width*2;
}


// compute perimeter
template <class DataType>
void Rectangle<DataType>::computePerimeter(const float& length, const float& width)
{
  perimeter = length*2 + width*2;
}

// compute area
template <class DataType>
void Rectangle<DataType>::computeArea(const float& length, const float& width)
{
  area = length*2 * width*2;
}


#endif 


Rectangle.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include "Rectangle.h"
#include "Rectangle.h" // to test #ifndef
#include "Fraction.h"
	

#include <iostream>
using namespace std;

int main()
{
  // name and assignment's title
  cout << "Lab 2b\n";
  cout << "Programmer: Justin Yu" << endl;
  cout << "Description: This lab will use class templates to make rectangle calculations" << endl << endl;
  
  
  Rectangle<float> a (10, 2);
  float t = a.getLength();
  cout << "Constructor length is: " << t << endl;
  float l = a.getWidth();
  cout << "Constructor width is: " << l << endl << endl;
  
  // set length
  a.setLength(10);
  float x = a.getLength();
  cout << "Length: " << x << endl;
  
  // set width
  a.setWidth(2);
  float y = a.getWidth();
  cout << "Width: " << y << endl;
  
  
  // compare sides return largest side
  if (a.compareSides(x,y))
    cout << x << " > " << y << endl;
  else
    cout << x << " < " << y << endl;
  
  // compute perimeter
  a.computePerimeter(x,y);
  cout << "Perimeter: " << a.getPerimeter() << endl;
  
  // compute area
  a.computeArea(x,y);
  cout << "Area: " << a.getArea() << endl << endl;
  
  cout << endl;
  
  ///*******************************************************************************
  // Fraction rectangle
  
  cout << "Fraction length and width " << endl;
  
  Fraction topF;
  Fraction botF;
  
  topF.numerator = 1;
  botF.numerator = 2;
  topF.denominator = 3;
  botF.denominator = 4;
  
  Rectangle<Fraction> b (topF,botF);
  
  cout << "Length: ";
  b.getLength();
  cout << endl;
  
  cout << "Width: "; 
  b.getWidth();
.
.
.
.
.
.
.
rest of my code
}


The problem I have is in Rectangle.cpp
I've tried to get the width and length of the fraction object that I passed into my class template constructor but when I run my program I don't get any values for my length and width for the rectangle<Fraction>

I set my length and width to <DataType> so I can't see the problem. My program compiles and everything.

Any help would be greatly appreciated!
Last edited on
Lines 66 and 70 are not passed to cout.
cout << "Lenght" << b.getLength() << endl;

By the way, that's not how you sum fractions, and operator> is wrong too.
Thanks, but I am not able to cout b.getLength() or b.getWidth() because I think it's not letting me since the << operator is not overloaded. I get the error "INVALID OPERANDS TO BINARY EXPRESSION"

I got around this earlier by using
1
2
  float x = a.getLength();
  cout << "Length: " << x << endl;


However I cannot cout a fraction object. I also am not allowed to add to the public interface of the class so I've been kind of trying to write a function within my Rectangle.cpp like
1
2
3
4
5
6
7
8
// return fractions
void returnFraction()
{
  cout << numerator << '/' << denominator;
}

But.. of course this isn't working at all... Any tips? 
 
Oh that's right, I completely overlooked that.
You need to implement std::ostream& operator<<(std::ostream&, const Fraction&) to use cout with Fraction in the same way you do with all other types.
The implementation logic is actually what you already wrote.
Pay attention to return the same ostream you pass, this way you can chain calls to operator<<
Fraction.h:
1
2
3
4
5
6
7
8
9
10
11
#include <iosfwd>
// ...
struct Fraction
{
  int numerator;
  int denominator;

};

// ...
std::ostream& operator<<(std::ostream&, const Fraction&) ;


Fraction.cpp:
1
2
3
4
5
6
7
8
9
#include <iostream>
// ...

std::ostream& operator<<(std::ostream& os, const Fraction& f)
{
    return os << f.numerator << " / " << f.denominator ;
}

// ... 



http://ideone.com/BAfbBl
Thanks for the tips. However, my professor told me I can only add things to the Rectangle.cpp file. I had something similar to print out my fractions in my .h but my teacher docked me points and kicked my lab back to me saying I cannot do that and any functions I want need to be in my Rectangle.cpp
So implement the operator overload (or named function if you prefer) in your main.cpp or rectangle.cpp. It could be argued that it belongs in rectangle.h/cpp as a helper function if it isn't allowed in fraction.h/cpp. You could make the same argument for main.cpp if it isn't allowed in the other header/source files.
Exactly! I tried to explain to my professor that my similar helper function was just used to print out my fractions but he said if I wanted to use it I needed to put it in my main.cpp/rectangle.cpp

To be honest I wasn't too sure how to put my helper in my main.cpp but I'll give it a shot with your tips and see if I can get it to work.
cire,

Sorry for all the questions but I'm trying to use the code you provided in my Rectangle.cpp

I'm using it like this in my program but it does not seem to be compiling. Can you see what I'm doing wrong?

1
2
3
4
5
6
7
8
9
10
11
12
#include "Rectangle.h"
#include "Rectangle.h" // to test #ifndef
#include "Fraction.h"
	
#include <iosfwd>
#include <iostream>
using namespace std;


int main()
{
  std::ostream& operator<<(std::ostream&, const Fraction&);
If you're going to define it in your main.cpp I would just do it like so:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include "Rectangle.h" // to test #ifndef
#include "Fraction.h"

// iosfwd was so you didn't have to #include <iostream> in a header file,
// no point in #including it where we're going to #include <iostream> anyway.	
#include <iostream>
using namespace std;

// If we're defining it in main, there's not much point in putting a prototype in a header,
// however you could put one here and move the definition after main if you preferred.
ostream& operator<<(ostream& os, const Fraction& f)
{
    return os << f.numerator << " / " << f.denominator ;
}

int main()
{
    // And, somewhere below:  cout << yourFraction
}
cire,

Thanks so much for your help! I would have been totally lost if you hadn't pointed me in the right direction. I'm going to try and get my program done tonight. I'll post more if I run into any more issues.

Thanks again!
So I submitted my program and got it sent back again today :(

The teacher commented "const Fraction" is not an immutable reference -- it's a copy. Fix and resubmit"

I don't understand why my const Fraction is not an immutable reference. Doesn't putting const in front of it make it immutable?

If anyone could help me out here I'd greatly appreciate it.

Here is my code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
#include "Rectangle.h"
#include "Rectangle.h" // to test #ifndef
#include "Fraction.h"
	
#include <iostream>
using namespace std;

ostream& operator<<(ostream& os, const Fraction& f)
{
  return os << f.numerator << "/" << f.denominator ;
}

int main()
{
  Rectangle<float> a; /*(10, 2);
  float t = a.getLength();
  cout << "Constructor length is: " << t << endl;
  float l = a.getWidth();
  cout << "Constructor width is: " << l << endl << endl;
  */
                      
  // set length
  a.setLength(10);
  float x = a.getLength();
  cout << "Length: " << x << endl;
  
  // set width
  a.setWidth(2);
  float y = a.getWidth();
  cout << "Width: " << y << endl;
  
  
  // compare sides return largest side
  if (a.compareSides(x,y))
    cout << x << " > " << y << endl;
  else
    cout << x << " < " << y << endl;
  
  // compute perimeter
  a.computePerimeter(x,y);
  cout << "Perimeter: " << a.getPerimeter() << endl;
  
  // compute area
  a.computeArea(x,y);
  cout << "Area: " << a.getArea() << endl << endl;
    
  // Fraction rectangle
  Fraction topF;
  Fraction botF;
  
  topF.numerator = 1;
  botF.numerator = 2;
  topF.denominator = 3;
  botF.denominator = 4;
   
  Rectangle<Fraction> b (topF,botF);
  
  cout << "Length: ";
  cout << topF;
  cout << endl;
  
  cout << "Width: ";
  cout << botF;
  cout << endl;
  
  // compare sides return largest side
  if (b.compareSides(topF,botF))
    cout << topF << " > " << botF << endl;
  else
    cout << topF << " < " << botF << endl;

  // compute perimeter
  b.computePerimeter(topF,botF);
  cout << "Perimeter: " << b.getPerimeter() << endl;
  
  // compute area
  b.computeArea(topF,botF);
  cout << "Area: " << b.getArea() << endl << endl;

  
  // object copy testing with assignment UPON declaration
  {
    cout << endl;
    Rectangle<float> copyA;

    const float copyX = x;
    const float copyY = y;
    
    // set length
    copyA.setLength(10);
    //copyX = copyA.getLength();
    cout << "object copy testing with assignment UPON declaration" << endl;
    cout << "Length: " << copyX << endl;
    cout << "Width: " << copyY << endl;
    
    // compare sides return largest side
    if (copyA.compareSides(copyX,copyY))
      cout << copyX << " > " << copyY << endl;
    else
      cout << copyX << " < " << copyY << endl;
    
    // compute perimeter
    copyA.computePerimeter(copyX,copyY);
    cout << "Perimeter: " << copyA.getPerimeter() << endl;
    
    // compute area
    copyA.computeArea(copyX,copyY);
    cout << "Area: " << copyA.getArea() << endl << endl;
    
    Rectangle<Fraction> copyB;
    const Fraction copyTopF= topF;
    const Fraction copyBotF = botF;
    
    cout << "Length: ";
    cout << copyTopF;
    cout << endl;
    
    cout << "Width: ";
    cout << copyBotF;
    cout << endl;
    
    // compare sides return largest side
    if (copyB.compareSides(copyTopF,copyBotF))
      cout << copyTopF << " > " << copyBotF << endl;
    else
      cout << copyTopF << " < " << copyBotF << endl;
    
    // compute perimeter
    copyB.computePerimeter(copyTopF,copyBotF);
    cout << "Perimeter: " << copyB.getPerimeter() << endl;
    
    // compute area
    copyB.computeArea(copyTopF,copyBotF);
    cout << "Area: " << copyB.getArea() << endl << endl;

  }

  {
    // object copy testing, with assignment AFTER declaration
    Rectangle<float> copyA;

    float copyX (0);
    copyX = x;
    float copyY (0);
    copyY = y;
    
    // set length
    copyA.setLength(10);
    //copyX = copyA.getLength();
    cout << "object copy testing with assignment AFTER declaration" << endl;
    cout << "Length: " << copyX << endl;
    cout << "Width: " << copyY << endl;
    
    
    // compare sides return largest side
    if (copyA.compareSides(copyX,copyY))
      cout << copyX << " > " << copyY << endl;
    else
      cout << copyX << " < " << copyY << endl;
    
    // compute perimeter
    copyA.computePerimeter(copyX,copyY);
    cout << "Perimeter: " << copyA.getPerimeter() << endl;
    
    // compute area
    copyA.computeArea(copyX,copyY);
    cout << "Area: " << copyA.getArea() << endl << endl;
    
    Rectangle<Fraction> copyB;
    Fraction copyTopF;
    copyTopF = topF;
    Fraction copyBotF;
    copyBotF = botF;
    
    cout << "Length: ";
    cout << copyTopF;
    cout << endl;
    
    cout << "Width: ";
    cout << copyBotF;
    cout << endl;
    
    // compare sides return largest side
    if (copyB.compareSides(copyTopF,copyBotF))
      cout << copyTopF << " > " << copyBotF << endl;
    else
      cout << copyTopF << " < " << copyBotF << endl;
    
    // compute perimeter
    copyB.computePerimeter(copyTopF,copyBotF);
    cout << "Perimeter: " << copyB.getPerimeter() << endl;
    
    // compute area
    copyB.computeArea(copyTopF,copyBotF);
    cout << "Area: " << copyB.getArea() << endl << endl;
  }
 
}




Any ideas? I'm totally stuck right now. I'm also not too clear about what my teacher meant. I'm guessing he's referring to this part of my code?

1
2
3
    Rectangle<Fraction> copyB;
    const Fraction copyTopF= topF;
    const Fraction copyBotF = botF;
Try using const Fraction&
(& means reference)
Thanks! Will try my luck again with my professor!
Topic archived. No new replies allowed.