Skip to main content
gamedev.net
🔒 Locked

C++ Code errors Constructors

Started by Ov3 Mar 27, 2009 at 6:39 PM 5 replies 600+ views
Original Post
Ov3
Ov3
Hi, im kinda new to C++, I just read some guides and books... im trying out constructors, as I want to create an online game later on, and I want to create the enemies quickly. This is the code Im having some trouble with: #include #include using namespace std; class gEnemy { public: unsigned int wspd; // The walking speed of an enemy unsigned int atk; // The attack power of an enemy unsigned int def; // The defense rate of an enemy unsigned int aspd; // The attack speed of an enemy unsigned int hp; // The amount of health points of enemy unsigned int lvl; // The level the monster is at char name[20]; // the name of the monster gEnemy(char *str, int wspd, int atk, int def, int aspd, int hp, int lvl) //monsters constructor { strcpy_s(name, str); } void showInfo() { cout << name << " has " << wspd << " walking speed, " << atk << " attack power,\n" << def << " defense, " << aspd << " attack speed, " << hp << " health points and is Lv " << lvl << "\n\n"; } }; int main() { gEnemy Monster1("Monster1", 5, 10000, 50000, 75, 20000, 111); gEnemy Monster2("Monster2", 3, 10000, 75000, 40, 40000, 111); Monster1.showInfo(); Monster2.showInfo(); system("PAUSE"); return 0; }; The problem with this is that all the values seems to be set to 3435973836 when I run the program, with both the monsters, even though I wrote other values in contructing... Why dont they get the right value? Do I use too many paramenters, any code errors? It compiles perfectly though... Help please :D
CodeCriminal
CodeCriminal
because your not assigning them the values passed to the constructor..
in order for the members of your class to actually have values you have to do something like this

// note: i noticed you were defining the constructing inside the class definition//the following code is how to define a ctor outside the definitiongEnemy::gEnemy( .... ){this->wspd = wspd;this->hp = hp;// and so on..}


otherwise the members will be considered uninitialised and thus containing 'gibberish' values such as you are getting.
usually the 'this->' wouldnt be placed there but because you have given the parameters of the constructor the same names as the members (variables of a class) it has to be.

Try not to do things like 'wspd' instead type out its full name like WalkSpeed, walkSpeed, walk_speed or m_WalkSpeed ( m is for member ) and so on. The reason for that is, it 'self comments' your code which means there is no need for the a comment at the side of each variable and is easier to understand throughout the rest of your code. Also why does your class name start with a g? g usually stands for global and that class isnt a global its a 'type' or 'blueprint' for a variable ( an instance of the class commonly called an object ).

Hope that was understood
~CC
Ov3
Ov3
Thanks, Ill try that...

Also, im used to the short words, I think they are easy to remember, but it varies...
Also, the 'g' in front of the class is because its not the whole thing... it means ground monster, and this is just a sketch anyway, so it doesnt matter..
Ov3
Ov3
hehe, ok thanks, it worked now. ill keep this in mind :D
as I said, im still inexperienced in c++ and programming in general, so its very good when you people help me out ^^
CodeCriminal
CodeCriminal
Quote:
Original post by Ov3
hehe, ok thanks, it worked now. ill keep this in mind :D
as I said, im still inexperienced in c++ and programming in general, so its very good when you people help me out ^^


Thats not a problem dude, everyone has to start somewhere, and im pretty positive i made some silly mistakes when i first started out also [smile].
However i still think you should stop abbreviating the names of your variables and types unless your using the Hungarian Notation nameing convention.

But its up to you in the end i guess.
Ov3
Ov3
Yeah, I probably should XD

im changing it now, and ill try to remember x)
dmatter
dmatter
Quote:
Original post by Ov3
Hi, im kinda new to C++, I just read some guides and books...
As your in the learning stage I think there is some benefit to me pointing out some good practices for modern C++ coding:

1) Don't apply using namespace std; in a header file (I assume that's what this is), because it'll ripple down to other files and pollute the namespace, better to use fully qualified names instead, e.g. std::cout

2) Descriptive names are favoured by most people really, like GroundEnemy rather than gEnemy and attackSpeed over aspd.

3) Don't use char arrays/C-style strings and string manipulation functions, use the modern C++ equivalent: std::string name;

4) Constructors need to initialise the variables otherwise, as you've found, they contain nonsense values. To construct member variables directly from the constructor's parameters you can use an initialisation list:

GroundEnemy(const std::string & name, int walkSpeed, int attackPower, int defenceRate, int attackSpeed, int health, int level)  : name(name)  , walkSpeed(walkSpeed)  , attackPower(attackPower)  , defenceRate(defenceRate)  , attackSpeed(attackSpeed)  , health(health)  , level(level){}
Using initialiser lists like is the preferred way rather than assigning variables individually like CodeCriminal's suggestion.

5) Rather than a showInfo function you can overload the output stream operator:

class GroundEnemy{public:    /* stuff */    // This line is only needed if the variables aren't public, and really they shouldn't be.    friend std::ostream & operator<<(std::ostream & os, const GroundEnemy & e);};std::ostream & operator<<(std::ostream & os, const GroundEnemy & e){    os << name << " has "       << walkSpeed << " walking speed, "        << attackPower << " attack power,\n"       << defenceRate << " defense, "        << attackSpeed << " attack speed, "       << health << " health points and is Lv " << lvl << "\n";    return os;}// Now you can simply do this to display monsters:std::cout << monster1 << "\n" << monster2;


6) Don't use system("PAUSE") because it's non-portable and completely overkill to ask the operating system to pause your program and wait for a key. Instead just wait for a single character to appear on the input stream with this: std::cin.get(); You could print out a "Press Any Key" message beforehand too if you wanted.

7) The return 0 is actually optional, the compiler will add it for you if you omit it, so unless you plan on returning anything other than zero then you might as well save yourself a line or two and get rid.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.