Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I want to be able to make a battle scene and put it into a function, but every time i try i have to create objects in a different header file, which i then cant call in main. To try to fix this i made the loop in the main function but it says the object calling the method must be modifiable.

//main.cpp
int main()
{
    Characters h;//Created using normal constructor
    cout << "Character: \n";
    h.setAttack(5);
    h.getAttack();
    h.setDefense(15);
    h.getDefense();
    Hero Me;
    cout << "Hero: \n";
    Me.setAttack(10);
    Me.getAttack();
    Me.setHp(5);
    Me.getHp();
    Hero::Hero(1,2,3,4);//Created using overloaded constructor
    Monsters m;
    cout << "Monster: \n";
    m.setAttack(20);
    m.getAttack();
    Monsters::Monsters(5,6,7,8);

//Problem is this this loop! i cant access the member functions for my objects.
//And i want to be able to put this in a function and call it from another file!
do
{
    cout << "Attacking!\n";
    cout << "Your 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.getStrength() << " damage;" << endl;
    Me.setHp() -= m.getStrength() ;//It compiles an error, saying its not modifiable
    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.setHp() -= Me.getAttack();
    cout << "Enemy hp is now: " << m.getHp() - Me.getAttack() << endl;
}while ((Me.getHp() >= 0) && (m.getHp() >= 0));

    if ((Me.getHp > 0) && (m.getHp < 0))
 cout <<"Congratulations! 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 my code.

//Hero.h
class Hero:
    public Characters
{

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

};


//Hero.cpp
int Herolevel;
int HeroHp;
int HeroStrength;
int HeroAttack;
int HeroDefense;

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

Hero::Hero(int newHp, int newLevel, int newAttack, int 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(void)
{
    cout << "Hero destroyed!\n";
}


//Monsters.h
#pragma once
#include "Hero.h"
#include "Characters.h"
class Monsters:
    public Characters //Hero
{

public:
    Monsters(void);
    Monsters(int, int, int, int);
    //Monsters(int);
    ~Monsters(void);
};

//Monsters.cpp
int Monsterlevel;
int MonsterHp;
int MonsterStrength;
int MonsterAttack;
int MonsterDefense;

Monsters::Monsters(void)
{
    "Monster Created";
}

Monsters::Monsters(int newHp, int newLevel, int newAttack, int 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(void)
{
    cout << "\nMonster Destroyed";
}


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


    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);
};


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

}

Characters::Characters(int random)//How can i make this work?
{
    cout << "Level " << level << " character created with: \n";
    /*srand ((unsigned)time(0));
    random = rand() % 10 + 1;
    setlevel(int random);*/
    level = random;

}

Characters::~Characters(void)
{
    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 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;
}
share|improve this question
    
Could you please include the exact error messages, and indicate the lines of your code where the errors came from. Also, and perhaps the best way for you to get the best possible answer, could you please minimize your code to include only the relevant parts? –  Mark Garcia Jun 14 '13 at 4:01
1  
Are you doing #include<Hero.h>, at start ? –  iKishore Jun 14 '13 at 4:03
    
Yes i included all the headers, but i thought they were irrelevant. Sorry. And oh okay next time i will only include relevant parts. I am new to this site...sorry about the problems –  BigD Jun 14 '13 at 4:22
    
What do you hope to accomplish with Hero::Hero(1,2,3,4)? I'm surprised that this would compile with this statement. You have quite a few problems with this code. You will have to ask a separate question for each problem. Alternatively, go to a C++ forum and ask for help there. One such place could be cplusplus.com. –  Adrian Jun 14 '13 at 5:50

2 Answers 2

To start with, don't declare the variables global, declare them as member variables! When you declare a global variable, there will be only one instance of that variable in your program, so if you create (for example) two Monster object both will be using the same global variables.

You also don't create any monsters except one, m. The second time you call the Monster constructor you don't create a new Monster object, just call its constructor. After you make the variables member variables (by simply declaring them in the class) you can use the non-default constructor like this:

Monster m;  // Uses default constructor
Monster m2(5, 6, 7, 8);  // Uses the other constructor

As for the problem you have, it's that getHp method only returns a copy of the hitpoints, and so the statement doesn't actually do anything (it modifies the returned copy, then throw it away). Instead you should call the setHp method:

Me.setHp(Me.getHp() - m.getStrength());
share|improve this answer
    
ohh! Thank you for the advice on the constructor. I had no idea! and as for the code, i tried using the method: –  BigD Jun 14 '13 at 4:39
    
Me.setHp(Me.getHp() - m.getStrength()); but im still getting the value -858993460 four times. –  BigD Jun 14 '13 at 4:40
    
@user2482488 That's because you change an otherwise uninitialized member variable. From the start, the member variabpel Hp is uninitialized, and contain a seemingly random value. Then setHp subtracts from that random value. Instead setHp should just assign to Hp. –  Joachim Pileborg Jun 14 '13 at 6:20

There seems to be a disconnect with how you are understanding OOP (object oriented programming) and C++ programming.

In C++ (and C), you must declare everything before you use it. So if you have a class that you need to use, you must declare it first. Otherwise you will get an error.

In OOP programming, an object is an instance of a class definition. A class has several key components, though not all may be present:

  1. Has a constructor:

    This sets up the initial state of any new instance of the class and usually allocates resources used by the object.

  2. Has a destructor:

    This deallocates resources used by the object.

  3. Has member variables:

    This is how the resources or other state information are attached to the object.

  4. Has member functions:

    This is how you operate on the object.

  5. Inherits from another class/struct:

    This states an is-a relationship with another class/struct type. I.e. A car is-a vehicle, a bike is-a vehicle. Thus car and bike inherits from vehicle.

Now, your Hero.h file contains the class declaration Hero indicating it's constructors and destructor (BTW, you don't need the (void). That is old C style. In C++ an empty parameter list like () is equivalent to (void).), but it doesn't contain any member variables or functions. This is because you have inherited from Characters. Except that you have not declared Characters before you are using it as a base class. So in your Hero.h file, you must state #include "Character.h" before the declaration of the class. This goes for each header file.

BUT you should also have a guard around the contents of your header in case you include that file multiple times. To do that put something like this around the contents of Hero.h.

#if defined HERO_H
# define HERO_H

... the contents of Hero.h ...

#endif

Do this for each of you header files. Use a UNIQUE guard name for each file. I.e. don't use HERO_H for your Character.h file. NOTE I just noticed you are using #pragma once. This is equivalent to using the guard but is not portable across all compilers.

Going into your Hero.cpp file, there are a few things wrong.

  1. You need to include the Hero.h file.

    Remember that C++ is declare before use and each source file is compiled separately. Therefore you must declare everything that is used by each source file before you use it. Since the Hero class is declared in the Hero.h header file, you must include that header file.

  2. Global variables:

    I see you are using global variables. Don't do that, not when you have member variables that are supposed to do the same thing. A member variable is part of every instance of that class. In other words, every time you create an instance of the class, you will have a unique memory storage location for that member variable allowing you to have multiple instances that will have different states which don't conflict with each other. I.e.:

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

    You also have a default constructor (it not called a 'normal' constructor) for Hero. Why? What is the point of having this? If there is a point, what are the defaults that need to be set for it? Looking at the Character class, I see that you also have not initialised the member variables for the instance either when you call its default constructor. I think the problem you are having here is that you don't know how to initialise an object which inherits from another, which is reasonable since it's not immediately obvious. Look at my last code fragment, and compare it to this new one:

    Hero::Hero(int newHp, int newLevel, int newAttack, int newDef)
      : Character(newHp, newLevel, newAttack, newDef) // <== initialiser list
    {
        cout << "Hero created using Overloaded function!\n";
        cout << "Hp is: "<< Hp << endl;
        cout << "level is: " << level << endl;
        cout << "Attack is: " << Attack << endl;
        cout << "Defense is: " << Defense << endl;
    }
    

    By using the initialiser list, I am initialising the base object by calling it's constructor that takes parameters. Doing it this way removes the need to have a base class that must have a default constructor or you can use the default constructor to generate the random values that you are looking for when calling its constructor that takes a single int value, thus removing the need for that constructor. For a description on how to use the rand() function, see here.

    An initialiser list is just that, a list used to initialise the object. Thus it can contain multiple things (hence why it's called a list). The other things it can contain are initial values of member variables.

    Characters::Characters(int newHp, int newLevel, int newAttack, int newDef)
      : Hp(newHp), level(newLevel)  //... etc
    {
    }
    

    These need to be in the order of base class initialiser (like in the Hero example) and then the member variables in the order that they appear in the class declaration. Some compilers will allow this to be in any order, but again, this is not portable and may result in unexpected behaviour.

Oh, one other thing I noticed is that your Monster.h file includes Hero.h. Why? Does the Monster.h file use an instance of Hero? No. So get rid of it.

share|improve this answer
    
OMG this made it sooooooo much clearer! thanks a bunch for your time and patience in willing to help me out! –  BigD Jun 14 '13 at 11:34
    
regarding OOP,and what you have taught me, when i create my object (for example) Hero Me(100,20,30,40); Monsters m(100,16,18,20); –  BigD Jun 14 '13 at 11:39
    
it initalises m and Me to those parameters right? So why when i call the get hp or get attack from m and ME, its a different value? –  BigD Jun 14 '13 at 11:40
    
I dunno. There were so many problems with the code I doubt that it looks the same. Quite honestly, this was a bad question from the start and my answer, though extensive, had IMO touched too many points that were beyond the scope of the question. If you like the answer, click the up arrow. If it answers your question, click the check mark under the up and down arrows. If you have another question, figure out what that question is and make a new one. –  Adrian Jun 14 '13 at 13:29

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.