Suggestions on how to use classes

Some background info: I'm taking three online courses in programming (all free, they're for my high school diploma). The first one is 2 weeks, the second is 3 weeks and the third one is 5 weeks. Long story short, I'm on the last course now and I need to finish it in 3 weeks. The last time I relied on just my book, the tutorial on this site and examples and exercises provided to me by the teacher, I found myself going back and relearning everything. Considering the magnitude of this course (it covers twice as much as the last two courses do together), I don't feel like I can afford this.

So, classes. The central part of this course. I've read the chapter in the book. I've read the tutorial here. And I'm going to take a look at the exercises in the book. But I know that I won't learn it properly this way. So I need some ideas on how to put classes to use. All the really simple programs I know my book provides me, but something slightly larger, perhaps? I've no idea what that could be, though.

In order to be productive, I'll state what I have learned so far:

* Statements (if, else, while, do, for, switch, break, continue)
* Strings (string class)
* Arrays and char arrays
* Functions
* Basics of pointers and references
* I've touched vectors, enum, new and delete
* I know basically how to make a simple class with constructors and destructors, with members and objects.

I suppose you could say that making practical use of classes (and pointers) is what I need to work on. Exercises are for passing the course. I want to excel at it. So, suggestions, anyone?
Last edited on
So I need some ideas on how to put classes to use.


I suck at coming up with situations on my own, so the easiest way for me to help with this would be for you to post an idea for a program -- then I could explain how classes could be applied.
I would suggest doing something that will challenge you. Things I've seen on this site you could do are a bignum class or an equation solver. Other things you didn't mention are, stacks, ques, trees, search methods, file input/output and linked lists. If you know all of that then you'll probably cover the basics.
I would say that the best way to really get information to stick is by doing something that is interesting and/or meaningful to you.
I suck at coming up with situations on my own, so the easiest way for me to help with this would be for you to post an idea for a program -- then I could explain how classes could be applied.

Well, how about a simple game that runs on the console? I'm not sure what games would be appropriate to try to program.


I would suggest doing something that will challenge you.

I couldn't agree more. However, I don't want to take on a challenge that is beyond me.


Other things you didn't mention are, stacks, ques, trees, search methods, file input/output and linked lists

Yeah, stacks, ques, trees, file input/output, templates come later on in the course. They're part of other chapters and according to the teacher, do not have the same amount of importance as classes and pointers do. Inheritance and friendship are brought up in the three most important chapters of the book (the first two are about classes and the third is about inheritance). Now, I don't want to spend too much time on the exercises in the book because they're little more than time wasters.
Last edited on
http://www.cplusplus.com/forum/articles/12974/
Try the one with bunnies (last one).

Other than that, I can't really suggest anything. As Disch said, think of what you want to write and then add classes to it.

Browni, neither bignum class, nor equation solver is a simple project (ok, I could see bignum class happening maybe..).

Well, how about a simple game that runs on the console?
since I'm editing my post, I'll say this before Disch does! http://www.cplusplus.com/forum/articles/28558/
Last edited on
I've read that article, haha, and I really do agree with it. However, it's ultimately about learning how to use classes and pointers, and I have a few other things to pick up as well (all in all, the course is almost 400 pages, with half of those being related to classes). If you think taking my time to deal with graphics will be more productive in my learning about these things then I'm all for it. Once I'm done with this I'm going to want to learn how to make simple 2D games anyway.

I'm going to check out those exercises you provided! Thanks a lot! =D
The goal of classes is to objectify things -- which basically meets to consolidate all the code to represent a thing or an idea into one area. That way using that thing is as simple as calling a function -- it's impossible/difficult to screw it up using the class.

For a game, you might objectify enemies:

1
2
3
4
5
6
7
class Enemy
{
public
  // functions might be things that an enemy would do
  void Attack(Player& player);  // attack a player
  action AI();  // determine the enemy's next action
}
That bunny thing sounds interesting, but it requires knowledge of file input/output, sorting, linked lists and "advanced classes", not sure what that is... but I'll save it for the weekend or something, when I've read up a bit more in the book. So any other suggestions? Can you utilize classes for games like hangman or tic-tac-toe without making the code too contrived?

What about some kind of text simulator battle like you suggested, Disch? You could have an Enemy class and a Hero class. The Hero could have member functions like Attack, Magic, Skill or whatever, as well as have stats that may be input by the player before the battle (within certain limitations of course). Same could go for abilities, a list of available abilities could be presented and you could pick the ones you like. The Enemy object would have all these things predetermined.

So once we have our Hero object and Enemy object, the battle part shouldn't be impossibly hard. Good idea or bad? I'll start off basic of course, with just health and attack. The other stuff I add on later.
Nope, I'm pretty much screwed, there's no way I can learn what I need to learn like this. Are people okay with being constantly pestered with questions? My teacher is useless, when I asked him about pointers he emailed me a link to some online tutorial that was mediocre at best. :/
Courses (online or in university/education centers) are a waste of both time and money. They might actually be contra-productive, because the matter being taught is usually outdated or just plain wrong.
If you're serious about learning programming and C++ in particular, you should buy the C++ Primer and drop all courses.
@Athar: I wish I could but it's for my high school diploma (basically, finishing this course adds 100 points to my total. After this I'll have 1850 points and 2250 is required in order to apply for university). In two weeks, when my friend is done with it, he's going to let me borrow that book (4th edition, of course). But for now, this is more or less mandatory. Need to do it. I'm very much serious about learning C++ but right now I have to conform to the course.

Expecting me to digest 200 pages about classes in 2 weeks is absurd, I'm not freakishly talented in programming. The book, I realize, is not going to let me accomplish this. I'm currently trying to create some text-based battle system for a standard RPG using classes but, since I've been dealing with classes for 2 days, I'm still wet behind the ears. Here's what I've got so far (I whipped this up yesterday, haven't touched it since due to reading the book the whole day):

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
/*
Str stands for Strength.
Def stands for Defense.
Lvl stands for Level.
Mod stands for Modifier.
Dmg stands for Damage.
rTime stands for random time and refers to the variable used to store the value returned by rand();
*/

class Character
{
  public:
    void charStats();
    int cmdAttack();
  private:
    float *Lvl, *Str, Def, *Atk, Base, Bonus, Mod, Dmg, rTime;
} Hero, Enemy;

void Character::charStats()
{
  Lvl = new float; //Shouldn't I
  Str = new float; //delete these at some point...
  Atk = new float; //...to release memory?
  *Lvl = 1;
  *Str = 17;
  *Atk = 10;
}

int Character::cmdAttack()
{
  srand( time(0) );
  rTime = rand() % 10;
  Base = *Atk;
  Bonus = *Str;
  Mod = *Str + (*Str + *Lvl) / 8;
  if (rTime > 6)
    Dmg = Base * Mod;
  else
    Dmg = Base * Bonus;
  return (Dmg);
}


So I'm looking at this code and I get several ?'s popping up. Like, if I want to expand and allow the use of skills and items, is this doing it wrong or not? How do I, in damage, take into account stats from another object of the same class? For instance, what if I don't want the value of Base to be Str, but Str - Def, where Def is a variable that belongs to the object of that which I perform the attack against (so to speak). Is it a good idea to implement constructors and destructors here? How?

This is what goes through my head, and reading my book isn't giving me any further insight. =/
Last edited on
1. Yes, you need to delete any objects that were created with new.
The use of pointers in this case is inappropriate. Change Lvl, Str and Atk to regular float variables and all problems are gone.

2. Choose function names (and other identifiers) so that it's obvious what the function does. setDefaultStats would have been better than charStats (which you would expect to return the char's stats).

3. srand(time(0)); does not belong into that function. It should be called once at the beginning of the program.
Make sure to look up what srand does to understand why.

4. Why are Base, Bonus, Mod, Dmg and rTime class members? Are they properties that all Character objects have?
Probably not, so they should be local variables in cmdAttack().

5. Since attacking always needs two characters, you need to pass the character to be attacked to cmdAttack:
int Character::cmdAttack(Character& victim)
Since the function does not seem to perform the actual attack, it probably should be called calculateDamage and the victim reference should be const.
You can then access the other character's stats with i.e. victim.getDefence() (assuming you create the corresponding getters).

6. Character has no constructor, leaving it in an uninitialized state after creation. That's not how things should be, so make sure there is a constructor (it might make sense to have it call setDefaultStats).
I don't know what to say... I've no idea how to make a constructor that calls setDefaultStats(). Well I have an idea but it's not working:

Character (); //declaration
1
2
3
4
5
Character::Character ()
{
  Character::setDefaultStats(int, float, float, float, float);
}
 //definition 


As for (5), I'm equally clueless. The problem is that I'm fumbling in the dark, I've little idea what it is I'm really doing and, unfortunately, my book isn't being clear and concise. Normally I wouldn't let it get to me but I'm nearing the weekend and I'm still stuck on the first chapter about classes, and I have another one about it, then there's inheritance and friendship, then exceptions, and god knows what else.

EDIT: Yes, this is me getting frustrated and panicking :P
Last edited on
If you already had functions, you should know how to call them. It's done like this:
1
2
3
4
Character::Character()
{
  setDefaultStats();
}


As for 5)... do you know what references are? If not, you can look them up, but the essence is that they act as aliases for the object you initialize them with. You can think of them as self-dereferencing pointers.

Below is a complete example:

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
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;

class Character
{
  public:
    Character();
    int calculateDamage(const Character& victim) const;

    int getLevel() const {return level;}
    int getStrength() const {return strength;}
    int getDefence() const {return defence;}
    int getAttack() const {return attack;}

  private:
    void setDefaultStats();
    int level,strength,defence,attack;
};

Character::Character()
{
  setDefaultStats();
}

void Character::setDefaultStats()
{
  level=1;
  strength=17;
  attack=10;
  defence=4;
}

int Character::calculateDamage(const Character& victim) const
{
  const int baseDamage=getAttack();
  const int bonus=getStrength();
  const int multiplier=getStrength()+(getStrength()+getLevel())/8;
  const int enemyDefence=victim.getDefence(); //can now be used in damage calculation somehow
  const int rTime=rand()%10;
  if (rTime>6)return baseDamage*multiplier;
  else return baseDamage*bonus;
}

int main()
{
  srand(time(0));
  Character hero,enemy;
  int damage=hero.calculateDamage(enemy);
  cout << "The hero hits the enemy for " << damage << " damage." << endl;
}
Last edited on
NOTE: I'll edit this when I've read through your code example.

Yes, I've read up on both references and functions. I tried your suggestion before as well, didn't want to work. I maybe overlooked something due to my current state of frustration. I should take a breather or something...


Okay!

Let's start with what I don't understand:

1) In line 10 and 35, why is there a "const" after the parenthesis?
2) I understand that "const Character& victim" is referring to the adress of whatever we put in there (in the case of this program, it would be the object enemy who has the class type Character). However, when used as it is used in 40, would it not return a value of 4? The objects aren't supposed to share the same stats... but that's nitpicking, or I'm not getting it. Doesn't really matter since I'm trying to understand classes through this, not actually make a functioning game.

But here's what irks me most: What you wrote there is significantly different from what I wrote. At what point was I supposed to understand that I wanted setDefaultStats to be a private member rather than a public member? That I want each stat to be returned as a value through a function?

I understand that it takes a lot of practice, programming and experience to get to that level, but... where does one start? I could be solving things on my own, but I could be doing it the wrong way, as shown in the code I wrote and posted. I don't know.
Last edited on
1) It marks the function as a const member function, which means it is not allowed to modify any members or call non-const member functions. If a function never needs to change any members, it generally should be declared as const.

2) Not sure what you mean... victim.getDefence() will give you the enemy's defence, which is 4.
The hero and the enemy are not sharing any stats, their stats just happen to be equal. You can assign different stats to both if you want to.

At what point was I supposed to understand that I wanted setDefaultStats to be a private member rather than a public member? That I want each stat to be returned as a value through a function?

It just depends on your needs. The character's stats are private, so you cannot access them outside Character's member functions. The getter functions allow you to get the stats (but not modify them) outside the class.
Even inside the class using the getters has advantages: for example, you might later want to add items that can give stat bonuses. You probably wouldn't want to add these bonuses directly to the base stats, but rather add them every time a stat is requested, e.g. when calling getStrength(). So if your character has 10 strength and wears an item that grants him 2 additional strength, your strength variable could still be 10 (representing your base strength), but getStrength() would add the bonus and returns 12.

setDefaultStats might just as well be a public member function if you want to be able to call it on Character objects outside of the class.
Last edited on
Topic archived. No new replies allowed.