Welcome Guest [Log In] [Register]
We hope you enjoy your visit.


You're currently viewing the Ultimate 3D Community as a guest. This means that you can only read posts, but can not create posts or topics by yourself. To be able to post you need to register. Then you can participate in the community active and use many member-only features such as customizing your profile, sending personal messages, and voting in polls. Registration is simple, fast, and completely free.

Join our community!

If you are already a member please log in to your account to access all of our features:

Username:   Password:
Add Reply
Basic classes; and object oriented programming
Topic Started: Jul 19 2008, 10:52 AM (759 Views)
ashrat3000
Member Avatar
u3d raytracer
[ *  *  *  *  *  * ]
NOTE: I suck at tutorials, don't kill me here :P
Also Dr.best, I'm writing this in a hurry, so i didn't use any proper naming schemes.


Classes


C++ uses classes.
A class can kind of be related to objects in gamemaker. Here would be a simple program with a class "monster":

Code:
 

#include "monster.h"
#include <iostream>

using namespace std;

int main()
{
//create a new instance of monster
Monster ogre;

//display the stats
ogre.DisplayStats();

//Create a monster with dynamic memory
Monster* pOrc = new Monster("Orc",100,10,"Club");
pOrc->DisplayStats();

delete pOrc;
pOrc = 0;
}


Our result looks like this:
Quote:
 

Name = none
HP = 0
MP = 0
Weapon = none

Name = Orc
HP = 100
MP = 10
Weapon = Club

Press any key to continue...


Wait, how do the stats get printed to the screen? I don't see a cout anywhere, and the same function is called twice but different results are printed each time.

This is because the class "Monster" is calling the function. You do it the same way you would access a variable in a different object with GM, with the dot operator.

Now before continuing, let me explain how to create a class.

You saw we included "Monster.h". This is where our class is defined. Lets take a look at it.
Code:
 

//Monster.h
#include <string>

#ifndef MONSTER_H
#define MONSTER_H

class Monster
{
public:
Monster();
Monster(std::string name,int hp, int mp,std::string weapon);
void DisplayStats();
private:
std::string mName;
int mHp;
int mMp;
std::string mWeapon;
};

#endif

So, the first thing we don't know is #ifndef.
This line checks to see if MONSTER_H was defined yet, hence, if not defined. If it hasn't, #define defines it.

The reason this is included is because there may be multiple cpp files that include "Monster.h". Rather than defining the class over and over again, this makes sure it is defined only once.

Moving on, we see something called public and private. Every function (by the way, these functions are called methods) and every variable under "public" can be accessed with the dot operator. Anything under private can only be accessed by the methods of the class. For example:
Code:
 

Monster Ogre;
cout << Ogre.mName;
will give you an error. The reason is mName is a private data member and can only be accessed by the internal functions of the class. However
Code:
 

Monster Ogre;
Ogre.DisplayStats();
is valid, as it is under public. In practice, the methods are public and data members are private (unless you don't want to :P )

This is useful because you can control what the user inputs. For example, instead of modifying the health of the monster directly, you can make him do it through a function like SetHp(int hp). This way you can prevent the user from inputting a value such as -30. The function could be
Code:
 

SetHp(int hp)
{
if (hp >= 0)
mHp = hp;
}


Moving on, we see there are 2 functions called Monster(..). This is the constructor.
Constructors must have the same name as the class itself.
The constructor is called every time you create a new monster. You do not need to call this function on your own, this is the create event. There are 2 of the same function because of overloading, but that is not explained in my tutorial.

Note: Do NOT forget the semi colon after the class definition. This will mess you up.


Now we have defined the class, but we need to make the implementation file. This is a cpp file.
Code:
 

//Monster.cpp

#include <string>
#include "Monster.h"
#include <iostream>
using namespace std;

Monster::Monster()
{
mName = "none";
mHp = 0;
mMp = 0;
mWeapon = "none";
}

Monster::Monster(string name,int hp,int mp,string weapon)
{
mName = name;
mHp = hp;
mMp = mp;
mWeapon = weapon;
}

void Monster::DisplayStats()
{
cout << "Name = " << mName << endl;
cout << "Hp = " << mHp<< endl;
cout << "Mp = " << mMp<< endl;
cout << "Weapon = " << mWeapon<< endl << endl;
}

Now, you see we started all the functions with Monster::. This means that we are using the functions from the class "Monster". You only need to do this with the actual definition, not when you are calling the function.

Note that the constructors do not return anything, not even void.

This should be fairly simple to understand. You can see that the methods of Monster are able to access the private variables, as they are part of the class.


Now when we go back to the main file, things make more sense.
Code:
 

#include "monster.h"
#include <iostream>

using namespace std;

int main()
{
//create a new instance of monster
Monster ogre;

//display the stats
ogre.DisplayStats();

//Create a monster with dynamic memory
Monster* pOrc = new Monster("Orc",100,10,"Club");
pOrc->DisplayStats();

delete pOrc;
pOrc = 0;
}

You make a new instance of the class the same way you make an integer (with int) and a float (with float).
If you do not specify the constructor, like this:
Code:
 

Monster Ogre;
Then the default constructor will be used. The one that takes no arguments. This is why when we called DisplayStats() we got all blank values. If you do specify the constructors parameters:
Code:
 

Monster Ogre("Ogre",100,10,"Club");
then the other constructor will be used and you get some real values for your class.

Now, everything should make sense.


Except one thing. The arrow ( -> ).

When you use the "new" keyword, you can create a new variable, and you get the pointer to that variable. The same is applied for classes. You can create a "new" instance of that class the same way.

You should know that inorder to get the actual value of a variable through a pointer is to dereference it with the *.
Code:
 

int* pInteger = new int;
*pInteger = 5;
cout << *pInteger;

The same goes for your own class. You must dereference it before you can call functions or access variables. So the syntex would be:
Code:
 

Monster* pOgre = new Monster();
(*pOgre).DisplayStats();

But this is cumbersome, so you can just use the arrow:
Code:
 

Monster* pOgre = new Monster();
pOgre->DisplayStats();




Other things I missed:
-There is a constructor, as well as a destructor. This is the destroy event. You define it the same way as the contructor, except the name is always the class name preceded with ~. So in this case, the function name is ~Monster().
-Any .h files you make always use quotes rather than brackets when you #include them.



Well, I hope that helped someone. And made sense. :P
-ashrat3000


PS: If there are any typos, tell me. I dont have firefox spell check on this pc.


Edited by ashrat3000, May 25 2009, 12:55 AM.
그대를 사랑해


Offline Profile Quote Post Goto Top
 
Ruud v A
Member Avatar
Programmer · Artist
[ *  *  *  *  * ]
Nice! You could also tell something about the default constructor and operator overloading.

Veniogames
Vēnit, ut mē occidĕret.

I will not use Ultimate3d 2.x.x anymore - I am an Ogre C++ programmer.
Offline Profile Quote Post Goto Top
 
ashrat3000
Member Avatar
u3d raytracer
[ *  *  *  *  *  * ]
Well, operator overloading a bit complicating, so maybe in a different tutorial :P .
그대를 사랑해


Offline Profile Quote Post Goto Top
 
ashrat3000
Member Avatar
u3d raytracer
[ *  *  *  *  *  * ]
Well apparently there were some syntex errors I missed. I never actually compiled this tut so I never noticed. :P

Thanks bazza for pointing those out.
All fixed.


그대를 사랑해


Offline Profile Quote Post Goto Top
 
Bazza
Member Avatar
Forum God
[ *  *  *  *  *  * ]
can i do somthing like this?

Quote:
 
class object
{
void fuction();
class derived : public object{};
}
////////////////////////////////////////
header
////////////////////////////////////////
void derived::function(){//code};
My instinct is to hide in this barrel, like the wily fish.
Offline Profile Quote Post Goto Top
 
Bazza
Member Avatar
Forum God
[ *  *  *  *  *  * ]
arghh

1>Main.cpp
1>c:\users\bazza\documents\visual studio 2008\projects\oop2\oop2\monster.h(11) : error C2039: 'sting' : is not a member of 'std'
1>c:\users\bazza\documents\visual studio 2008\projects\oop2\oop2\monster.h(11) : error C2039: 'sting' : is not a member of 'std'
1>c:\users\bazza\documents\visual studio 2008\projects\oop2\oop2\monster.h(11) : error C2061: syntax error : identifier 'sting'
1>c:\users\bazza\documents\visual studio 2008\projects\oop2\oop2\main.cpp(15) : error C2661: 'Monster::Monster' : no overloaded function takes 4 arguments
1>Monster.cpp
1>c:\users\bazza\documents\visual studio 2008\projects\oop2\oop2\monster.h(11) : error C2039: 'sting' : is not a member of 'std'
1>c:\users\bazza\documents\visual studio 2008\projects\oop2\oop2\monster.h(11) : error C2039: 'sting' : is not a member of 'std'
1>c:\users\bazza\documents\visual studio 2008\projects\oop2\oop2\monster.h(11) : error C2061: syntax error : identifier 'sting'
1>c:\users\bazza\documents\visual studio 2008\projects\oop2\oop2\monster.cpp(17) : error C2511: 'Monster::Monster(std::string,int,int,std::string)' : overloaded member function not found in 'Monster'
1> c:\users\bazza\documents\visual studio 2008\projects\oop2\oop2\monster.h(8) : see declaration of 'Monster'
My instinct is to hide in this barrel, like the wily fish.
Offline Profile Quote Post Goto Top
 
skarik
Member Avatar
kitten eating scum
[ *  *  *  *  *  * ]
Replace all sting with string.


Headers really should only be at the top, but you could go crazy.
Blog|EHS
Offline Profile Quote Post Goto Top
 
Gandalf20000
Member Avatar
Geek
[ *  *  *  *  *  * ]
Great tutorial, Ashrat! It really helped me a lot to see how classes work, and helped me to start to see how pointers are used.
Offline Profile Quote Post Goto Top
 
« Previous Topic · Tutorials · Next Topic »
Add Reply