简体   繁体   中英

How to initialize instances of classes?

//main.cpp

#include "Monsters.h"
#include "Hero.h"
#include "Monsters.h"
#include "Characters.h"
#include <iostream>
#include <string>
using namespace std;

int main()
{

When i created my object it took those parameters and initialised them to it right? So why when i called their methods, it returned a different value? For example, I initialized them here while created my object at the same time:

    Hero Me(100,20,30,40);
    Monsters m(100,16,18,20);//creates a monster object and uses overloaded constructor to initialize

    Me.getHp();//expected 100, but got a long negative random number
    m.getHp();//expected 100, but got a long negative random number also

    //Why must i use setHp() and setAttack() when i already initialized them with the constructor?
    Me.setAttack(89);
    Me.setHp(100);

    m.setAttack(40);
    m.setHp(100);


    cout << "\nAttacking!\n";

    while ((Me.getHp() > 0) && (m.getHp() > 0))
    {   
        cout << "\nYour hp is: " << Me.getHp() << endl;
        cout << "The enemy's hp is: "<< m.getHp() << endl;
        cout << "\nThe monster has attacked you!\n";
        cout << "You received " << m.getAttack() << " damage;" << endl;
        Me.damageTaken(m.getAttack());
        if(Me.getHp() > 0)//Check if still alive
        {
            cout << "\nYour hp is now: " << Me.getHp() << endl;
            //cout << "Enemy hp is: "<< m.getHp() << endl;
            cout << "\nNow you attacked!\nYou have dealt "<< Me.getAttack() << " Damage" << endl;
            m.damageTaken(Me.getAttack());

            if(m.getHp() > 0)//Check if still alive
            {
                cout << "Enemy hp is now: " << m.getHp() << endl;
                cout << "\nAttacking again!\n";
            }
        }

    } 
        if ((Me.getHp() > 0) && (m.getHp() <= 0))
                cout <<"\nCongratulations! You killed the enemy!" << endl;

        else if ((Me.getHp() <= 0) && (m.getHp() > 0))
                cout << "You have died!" << endl;




    cin.sync();
    cin.get();
    return 0;
}

Here's the rest of the code in case you need it:

//Hero.h
#pragma once
#include "Characters.h"

class Hero:
    public Characters
{
private:
    int Herolevel;
    int HeroHp;
    int HeroStrength;
    int HeroAttack;
    int HeroDefense;

public:
    //Hero();
    Hero(int, int, int, int);
    ~Hero();

};

//Hero.cpp
#include "Monsters.h"
#include "Hero.h"
#include "Characters.h"
#include <iostream>
using namespace std;

//Hero::Hero()
//{
//  cout << "HOLA! Hero Created using normal constructor\n";
//}

Hero::Hero(int newHp, int newLevel, int newAttack, int newDef)
    : HeroHp(newHp), Herolevel(newLevel), HeroAttack(newAttack), HeroDefense(newDef)
{
    cout << "Hero created using Overloaded function!\n";
    HeroHp = newHp;
    cout << "Hp is: "<< HeroHp << endl;
    Herolevel = newLevel;
    cout << "level is: " << Herolevel << endl;
    HeroAttack = newAttack;
    cout << "Attack is: " << HeroAttack << endl;
    HeroDefense = newDef;
    cout << "Defense is: " << HeroDefense << endl;
}


Hero::~Hero()
{
    cout << "Hero destroyed!\n";
}

//Monsters.h
#pragma once
#include "Characters.h"
class Monsters:
    public Characters //Hero
{
private:
    int Monsterlevel;
    int MonsterHp;
    int MonsterStrength;
    int MonsterAttack;
    int MonsterDefense;
public:
    //Monsters();
    Monsters(int, int, int, int);
    //Monsters(int);
    ~Monsters();
};

//Monsters.cpp
#include "Monsters.h"
#include "Hero.h"
#include "Characters.h"
#include <iostream>
using namespace std;

Monsters::Monsters(int newHp, int newLevel, int newAttack, int newDef)
    : MonsterHp(newHp), Monsterlevel(newLevel), MonsterAttack(newAttack), MonsterDefense(newDef)
{
    cout << "Monster created using Overloaded function!\n";
    MonsterHp = newHp;
    cout << "Hp is: "<< MonsterHp << endl;
    Monsterlevel = newLevel;
    cout << "level is: " << Monsterlevel << endl;
    MonsterAttack = newAttack;
    cout << "Attack is: " << MonsterAttack << endl;
    MonsterDefense = newDef;
    cout << "Defense is: " << MonsterDefense << endl;
}

Monsters::~Monsters()
{
    cout << "\nMonster Destroyed";
}

//Characters.h
#pragma once
class Characters
{
private:
    int level;
    int Hp;
    int Strength;
    int Attack;
    int Defense;
public:
    Characters();
    Characters(int);
    Characters(int, int, int, int);
    ~Characters();


    int getAttack();
    int getDefense();
    int getStrength();
    int getHp();
    int getLevel();

    void setAttack(int);
    void setDefense(int);
    void setStrength(int);
    void setHp(int);
    void setlevel(int);
    void damageTaken(int);
};

//Characters.cpp
#include "Characters.h"
#include "Hero.h"
#include "Monsters.h"
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;


Characters::Characters()
{
    cout << "\nCharacter has been created!\n";

}

Characters::Characters(int random)
{
    cout << "Level " << level << " character created with: \n";
    srand ((unsigned)time(0));
    random = rand() % 10 + 1;
    //setlevel(int random);
    level = random;

}

Characters::~Characters()
{
    cout << "Character has been destroyed!\n";
}

void Characters::setAttack(int att)//get Character left over hp
    {
        Attack = att;
    }

void Characters::setDefense(int def)//get Character left over hp
    {
        Defense = def;
    }

void Characters::setStrength(int str)//get Character left over hp
    {
        Strength = str;
    }

void Characters::setHp(int health)//get Character left over hp
    {
        Hp = health;
    }

void Characters::damageTaken(int damage)//get Character left over hp
    {
        Hp -= damage;
    }

void Characters::setlevel(int lvl)//get Character left over hp
    {
        level = lvl;
    }


int Characters::getAttack()
{
    //cout << "Your attack is: " << Attack << endl;
    return Attack;
}

int Characters::getDefense()
{
    //cout << "Your defense is: " << Defense << endl;
    return Defense;
}

int Characters::getStrength()
{
    //cout << "Your strength is: " << Strength << endl;
    return Strength;
}

int Characters::getHp()
{
    //cout << "Your hp is: " << Hp << endl;
    return Hp;
}

int Characters::getLevel()
{
    //cout << "Your level is: " << level << endl;
    return level;
}

Hero inherits Characters , including all its data members (level, hp, etc.).

So, it doesn't need to add its own HeroLevel, HeroHP etc. You're just duplicating data (and work).

Now, it also doesn't initialize the base class members - the default constructor for Characters doesn't even zero them, so their values are undefined.

You should be looking for something like this:

class Characters
{
private:
    int level;
    int hp;
    int strength;
    int attack;
    int defense;
protected:
    Characters(); // zero everything by default
    Characters(int); // randomly generate everything
    Characters(int, int, int, int); // populate explicitly
public:
    int getAttack() const { return Attack; }
    // etc.
};

Characters::Characters() : level(0), hp(0), strength(0), attack(0), defense(0) {}
Characters::Characters(int seed) {
    // NB. your code still doesn't initialize hp, strength etc.
    // it also logs level before initializing it, so that will be garbage
}
Characters::Characters(int hit, int lvl, int att, int def)
 : level(lvl), hp(hit), attack(att), defense(def)
{
    // you only pass 4 attributes, what should strength be?
}

and finally:

Hero::Hero(int newHp, int newLevel, int newAttack, int newDef)
    : Characters(newHp, newLevel, newAttack, newDef)
{
    // logging goes here
    // note that you don't need HeroLevel etc. at all any more, just use level
}

You should really try to understand the basics of this before designing an entire class hierarchy - see juanchopanza's answer for a clear example. A smaller example would also have been much easier to paste, read and understand.

How to initialize instances of classes?

You need to correctly initialize your base classes by calling their constructor, passing on the relevant arguments. Maybe it is easier to illustrate this with a simpler example:

class Foo
{
 public:
  explicit Foo(int i) : foo_i(i) {}
  int getFoo() const { return foo_i; }
 private:
};

class Bar : public Foo
{
 public:
  explicit Bar(int i) : Foo(i) // calls Foo(int) constructor, setting Foo::foo_i 
  {}
};

#include <iostream>
int main()
{
  Bar b(42);
  b.getFoo(); // prints 42
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM