Sign in to follow this  
nullsquared

Weird values in classes.

Recommended Posts

Hi! I am having this problem with my classes in my game... For some reaon when I have a constructor that sets the value for the health to 50 or 50 times 2 I get numbers like -2 and 454572987!!!???!!! Heres the code:
#include <iostream>
#include <string>
#include <vector>
#include <cctype>

using namespace std;

class Enemy
{
    public:
           Enemy(int damage = 10, 
                 int defence = 5, 
                 int health = 50): 
                 m_Damage(damage), 
                 m_Defence(defence),
                 m_Health(health) {}
           
           int GetDamage() {return m_Damage;}
           int GetDefence() {return m_Defence;}
           int GetHealth() {return m_Health;}
           int SetHealth(int a)
           {
               m_Health = m_Health - a;
               if (m_Health < 0)
                   m_Health = 0;
           }
           
    private:
            int m_Damage;
            int m_Defence;
            int m_Health;
};

class Fairy: public Enemy
{
    public:
           Fairy(int magic = 20, int stars = 0): 
                     Enemy(Enemy::GetDamage()/2, 
                           Enemy::GetDefence()*2, 
                           Enemy::GetHealth()/2),
                     m_MagicDamage(magic), 
                     m_Stars(stars) {}
           
           int GetStars() {return m_Stars;}
           int GetMagicDamage() {return m_MagicDamage;};
           
    private:
            int m_Stars;
            int m_MagicDamage;
                          
};

class Orc: public Enemy
{
    public:
           Orc(): Enemy(Enemy::GetDamage()*2,
                        Enemy::GetDefence()*2,
                        Enemy::GetHealth()*2) {}
};

class Hero: public Enemy
{
    public:
           Hero(int stars = 0, int specialDamage = 25): 
                    Enemy(Enemy::GetDamage()*2,
                          Enemy::GetDefence()*2,
                          Enemy::GetHealth()*2),
                    m_Stars(stars),
                    m_SpecialDamage(specialDamage) 
           {
               cout<<"\nWhats your hero's name: ";
               string name;
               cin>>name;
               cin.ignore();
               
               name[0] = toupper(name[0]);
               m_Name = name;
           }
           
           int GetStars() {return m_Stars;}
           int GetSpecialDamage() {return m_SpecialDamage;}
           string GetName() {return m_Name;}
           
    private:
            int m_Stars;
            int m_SpecialDamage;
            string m_Name;
};

void displayItems(vector<string> &theInventory, Hero &theHero);
string allToUpper(string word);
bool tipFunc(bool &tip);

int main()
{
    cout<<"\t\t\t     Welcome to HaM!!!\n";
    cout<<"\t\t\t The ultimate adventure!!!\n";
    
    Hero theHero;
    cout<<"\nYou named your hero "<<theHero.GetName()<<".\n";
    
    vector<string> theInventory;
    displayItems(theInventory, theHero);
    
    // Debugging
    cout<<theHero.GetHealth()<<endl;
    Orc orc;
    cout<<orc.GetHealth();
    
    cout<<theHero.GetName()<<" can go in four directions:\n";
    cout<<"1) Up\n2) Down\n3) Left\n4) Right\n";
    
    cout<<"\nEnter the direction or the number: ";
    
    string answer;
    cin>>answer;
    cin.ignore();
    
    answer = allToUpper(answer);
    
    bool tip = false;
    
    while (answer != "2" && answer != "DOWN")
    {
        if (tip == false)
            tipFunc(tip);
            
        if (answer != "1" && 
            answer != "UP" && 
            answer != "3" && 
            answer != "LEFT" && 
            answer != "4" && 
            answer != "RIGHT")
            cout<<"\nPlease enter a choice from 1-4 only.\n";
            
        if (answer == "1" || answer == "UP")
        {
            cout<<endl<<theHero.GetName()<<" fell off a cliff.\n";
            theHero.SetHealth(10);
            cout<<endl<<theHero.GetName()<<"' health: "<<theHero.GetHealth()<<".\n";
        }
        cin.get(); // So the program doesnt end
    }
    
    cin.get();
    return 0;
}

void displayItems(vector<string> &theInventory, Hero &theHero)
{
    vector<string>::iterator iter;
    cout<<"\n"<<theHero.GetName()<<"' items:\n";
    if (theInventory.size() < 1)
        cout<<theHero.GetName()<<" has no items.\n";
    else
        for (iter = theInventory.begin(); iter != theInventory.end(); iter++)
        {
            cout<<*iter<<endl;
        }
    cout<<endl;
}

string allToUpper(string word)
{
    for (int i = 0; i < word.size(); i++)
        word[i] = toupper(word[i]);
        
    return word;
}

bool tipFunc(bool &tip)
{
    cout<<"\nHint: If your health goes down to 0 you lose.\n";
    tip = true;
}


Share this post


Link to post
Share on other sites
Quote:

Orc(): Enemy(Enemy::GetDamage()*2,
Enemy::GetDefence()*2,
Enemy::GetHealth()*2) {}


You are passing parameters to the base class constructor.
Those parameters are computed from members of the base object.
However, the base object doesn't exist yet - you are constructing it!
Therefore, you really are passing garbage to the constructor.

Share this post


Link to post
Share on other sites
The problem is that, when you are calling the Enemy constructor in your derived class's initializer list, you invoke Enemy's member functions BEFORE Enemy has been constructed.

So what you do is
(in Ork::Ork) Enemy::m_Damage=Enemy::m_Damage * 2
but at that point m_Damage is still uninitialized. Garbage in - garbage out. [smile]

[edit]Damn I'm slow...

Share this post


Link to post
Share on other sites
Quote:
Original post by agi_shi
So should I like give exact values instead of retrieving them?


Well, yes - there are no values to retrieve yet.

Share this post


Link to post
Share on other sites
Quote:
Original post by agi_shi
So should I like give exact values instead of retrieving them?


Yes. You could use static member variables, for example.

[edit][dead]

Share this post


Link to post
Share on other sites
Or like this


class Enemy
{
protected:
static const int base_damage=10;
static const int base_defense=5;
static const int base_health=50;
public:
Enemy( int damage=base_damage, int defense=base_defense, int health=base_health )
: m_Damage( damage )
, m_Defense( defense )
, m_Health( health )
{}
private:
int m_Damage;
int m_Health;
int m_Defense;
};

class Orc: public Enemy
{
Orc( int damage=base_damage*2, int defense=base_defense*2, int health=base_health*2 )
: Enemy(damage, defense, health)
{}
};



Share this post


Link to post
Share on other sites
OH YEAH! Thanks for the great idea... Since I'm a beginner let me explain this to myself and you tell me if I'm right... Since those are statics they arent constructed in the constructor itself... and since they are protected they are acceseble in the inherited classes... correct?

Share this post


Link to post
Share on other sites
Thanks a lot... I'm going along Beginning C++ Game Programming but none of the examples did this so I had to guess some things. Good Bye and thanks again.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this