Seeking guidance about classes

Hi all,

For my upcoming exam, I have to write/define/initialise classes.

Here's a question from my practice exam;

2. Conversion between imperial and metric units of weight
The metric base unit of weight is the gram – 1000 grams are one kilogram. The imperial
base unit of length is the pound, which can be divided into 16 ounces. 14 pounds are one
stone. One ounce weighs 28.349523125 grams.
Devise a class "weight" with appropriate get and set methods the units of weight mentioned
above that will perform conversions between metric and imperial units of weight. The class
should also work with the main program given below and must implement suitable methods:
1
2
3
4
5
6
7
8
9
10
11
#include<cstdio>
... // class definition
int main(void)
{
weight w;
w.setKilograms(77.5);
double stone,pounds;
w.getStoneAndPounds(stone,pounds);
printf("Someone who weighs 77.5kg weighs %.2f stone and %.2f pounds\n",stone,pounds);
return 0;
}


This looks unlike anything I've seen before with classes

Could anyone lend a hand and explain how I'd be able to answer the activity above?
Thanks in advance
1
2
3
4
5
6
7
8
9
class weight{
  private:
   double w;

  public:
   void setKilograms(double kg);
   void getStoneAndPounds(double& stone, double& pounds);
   //probably some more setters and getters...
};
- is what the declaration of your class will look like. Do you have any problems with understanding what the methods do?
thank you hamsterman,

I'm not entirely sure; I think the next step is
1
2
3
void :: setKilograms (double kg); {

}

but I don't know what to write in there.

I'm thinking that it depends how many grams/stone/ounces there are? But I wouldn't know how to write it as it happens :/



EDIT
I've had a think about it, and would I do;

1
2
3
4
5
6
7
8
9
10
11
12
void :: setKilograms (double kg, double g//grams//); {

kg = g * 1000
}


void :: setStoneAndPounds (double& stone, double& pounds) {

stone = pound * 16

pound = stone / 16
}

?

Would that be alright?
Last edited on
Shameless self-bump - I have to get this in my head.

I've been playing with it and here is my updated 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
#include <cstdlib>
#include <iostream>

#include <cstdlib>
#include <iostream>
#include <cstdio>


class weight{
  private:
   double w;

  public:
   void setKilograms(double kg);
   void getStoneAndPounds(double stone, double pounds);
};

void weight :: setKilograms (double g)
{
     g * 1000;
}

void weight :: getStoneAndPounds (double stone, double pounds)
{
     stone = 12;
     pounds = 2.2;
}

double stone = 12;
double pounds = 2.2;

int main(void)
{
weight w;
w.setKilograms(77.5);
double stone,pounds;
w.getStoneAndPounds(stone,pounds);
printf("Someone who weighs 77.5kg weighs %.2f stone and %.2f pounds\n",stone,pounds);

system ("PAUSE");
return 0;

}


It all compiles but stone and pounds come up as "0.00".
How do I make it so I can make %.2f stone and %.2f pounds\n print out what I want it to? I've even written out the values I want and it still doesn't work!!!!
The problem here is that you are creating multiple different variables with the same name.

Whenever you say "double foo;", that creates another, separate variable named foo.

Here, you have 3 different occurances of double stone. One on line 23, one on line 29, and again on line 36.

What's happening is this:

line 23:
stone and pounds are local to getStoneAndPounds only. They are not visible outside that function. You set them to 12 and 2.2, but then the function exits and the variables go out of scope. They're gone forever.

Basically the function does nothing. Just sets some values, but then the values disappear immediatley.

line 29, 30:
this creates global variables assigns them. These variables are visible for the rest of the program below those lines

line 36:
this creates another set of variables which "hide" the global variables. Now when you print stone and pounds in main, you are printing the local variables, and not the global variables


FURTHERMORE:

This function also does nothing:

1
2
3
4
void weight :: setKilograms (double g)
{
     g * 1000;
}


You're taking g and multiplying it by 1000, but you're not doing anything with the result.




THE SOLUTION:

Notice how your weight class has a 'w' member. This member is to record the weight. setKilograms is probably supposed to modify this w member.

getStoneAndPounds is probalby supposed to change stone and pounds depending on the value of 'w'.

Note that in order for getStoneAndPounds to output anything, you'll need to pass the values by reference. Change it to this:

void getStoneAndPounds(double& stone, double& pounds);

Note the '&' symbols. This means you're passing a reference to the variable, instead of making a separate copy of the variable (which was your problem before).
thank you Disch!

So is "W" supposed to be the variable that I take through the process of converting from grams all the way to stone and pounds? because I don't think I'd be able just to put the actual values :P
Yes, that's correct.
Disch,

The program only prints out the sum of the first class

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
void weight :: setKilograms (double kg)
{
    w = 77.5;
    w = w * 1000;
}

void weight :: setOunces (double ounce)
{
    w = w/16;
}

void weight :: setPounds (double pounds)
{
    w = w/14; 
}

void weight :: setStone (double stone)
{
     w = w;
}

void weight :: getStoneAndPounds (double& stone, double& pounds)
{
     stone = w;
}


How do I make it so that it goes all the way through? If you get what I mean?
EDIT
Here's the bottom of the code, I think this may be where the problem lies
1
2
3
4
5
6
7
8
9
10
11
12
int main(void)
{
weight w;
w.setKilograms(77.5);
double stone,pounds;
w.getStoneAndPounds(stone,pounds);
printf("Someone who weighs 77.5kg weighs %.2f stone and %.2f pounds\n",stone,pounds);

system ("PAUSE");
return 0;

}

Last edited on
Take a look at your set functions:

1
2
3
4
5
void weight :: setKilograms (double kg)
{
    w = 77.5;
    w = w * 1000;
}


What is that doing? What will happen when kg=20? Step through it and see if you can spot the mistake.

You have similar mistakes in setStone, setPounds, etc.

How do I make it so that it goes all the way through? If you get what I mean?


I have no idea what you mean, but whatever problem you're having might be related to the above, so fix that first and see if the problem goes away.
well the double kg is pretty much irrelevant, I was just filling in space.

kg can never equal 20, it's set at 75.5 - it's supposed to be static as represented at the end

1
2
3
4
5
6
7
8
9
10
11
12
int main(void)
{
weight w;
w.setKilograms(77.5);
double stone,pounds;
w.getStoneAndPounds(stone,pounds);
printf("Someone who weighs 77.5kg weighs %.2f stone and %.2f pounds\n",stone,pounds);

system ("PAUSE");
return 0;

}


I mean the output %.2f stone will always come out as whatever the value of the first class is here;
1
2
3
4
5
void weight :: setKilograms (double kg)
{
    w = 77.5;
    w = w * 1000;
}

so something in the code is restricting the "w" variable from going through all of the classes through all of the maths I've put in to calculate stone.
Oooh, okay now I see what you're thinking.

I think you're misunderstanding how it works. When you call a function, only that function is executed. If you want that function to call another function, you need to call that other function.

To step through what the computer is going to do:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
weight w;   // creates a weight object

w.setKilograms(77.5);  // calls 'setKilograms' on that object with kg=77.5

// - since you call setKilograms, the program then starts executing code from there:
  void weight :: setKilograms (double kg)
  {
      w = 77.5;  // sets w to 77.5  (but why aren't you setting it to =kg?)
      w = w * 1000; // then multiplies it by 1000  (w = 77500)
  }

// - now that setKilograms has ended, the program resumes where it was before
//   setKilograms was called:  back to main

double stone,pounds;
w.getStoneAndPounds(stone,pounds);
printf("Someone who weighs 77.5kg weighs %.2f stone and %.2f pounds\n",stone,pounds);



Notice that none of your other functions (setOunces, setPounds, etc) are being run. This is because you're never telling the computer to run them. You're only telling it to run setKilograms -- so that's all it does.



kg can never equal 20, it's set at 75.5 - it's supposed to be static as represented at the end


The whole point of passing things to functions is that different values can be used. What is the point of passing kg to that function if you're not using it?
Ohh I see. Well that explains that then. Thank you for your help btw.

But why would I need more than one "set" if I can just run all of the maths from inside one scope? The practice exam implies that I'd need more than just the "setKilograms"...and even then it really only implies that "setKilograms" should only be used to set up the kilogram value instead of the entire calculation.

I've tried adding more
1
2
w.setKilograms (77.5);
w.setStone;

etc. but it's not working...does that indicate that without adding more functions or whatever, that I can only get the result if I work within one void weight :: setWhatever?

I have no idea - in my opinion, using cin and cout are easier to use and you could probably do more with them in less space. I'm just working to meet a question criteria :/
But why would I need more than one "set" if I can just run all of the maths from inside one scope?


Well the idea is that multiple sets would allow you to set multiple different things.

Say for instance the user gave you a weight in pounds instead of kilograms. You could then just do: w.setPounds( whatever_the_user_gave_you );

Or if the user gave you the weight in stones you could say w.setStones, etc.


The practice exam implies that I'd need more than just the "setKilograms"...and even then it really only implies that "setKilograms" should only be used to set up the kilogram value instead of the entire calculation.


setKilograms logically should take a weight in kilograms, and store it in whatever format you want to store internally.

The question here is: what format do you want to store internally? What does 'w' represent? The weight in lbs? kgs? stones?


Whatever it is, setKilograms should take the user-provided weight, and completely convert it to whatever format you store internally.


Then, on the flip side, getStonesAndPounds should take that value 'w' and convert it to pounds and stones.

w.setStone;


To call a function, it needs parenthesis. You'd need to do w.setStone( some_weight_in_stones );

But it doesn't make any sense to do this in main, as you've already said you're already setting the weight in Kilograms.

Now if you want to chain these functions together.... like if converting to lbs is the first step in converting to stones then you should call the other function from setKilograms.


I have no idea - in my opinion, using cin and cout are easier to use and you could probably do more with them in less space.


That's because you're thinking of the program as a whole instead of just a small class. That's a problem many beginners face.

Focus on writing the class: weight. You're making something that manages a weight. You want to make this class easy and intuitive to use.

So what is easy and intuitive to use? Something like this:

1
2
3
4
5
6
7
weight myweight;

myweight.setPounds( 180 );  // I weigh 180 lbs
cout << "My weight in lbs is: " << myweight.getPounds() << endl; // print my weight in lbs
cout << "My weight in kgs is: " << myweight.getKilograms() << endl; // print my weight in kgs
cout << "My weight in stones is: " << myweight.getStones() << endl; // in stones
// etc 


The objective here is to write that class. So how would you write it so that you can use it like the above?

That's what this exercise is trying to teach you.
Last edited on
Ahhhh I see.
Thank you, you have been a massive help. Maximum credit to you :)
Topic archived. No new replies allowed.