How to initialize instances of classes? - c++

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

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
}

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.

Related

I have different output from the same code on Linux VSCode (gcc) and Windows Clion (visual c++)

I've made a text based game for my project in VSCode (gcc). The main problem is that VSCode gives me strange output while Clion (visual-c++) gives me the right one.
For example in VSCode I get negative numbers as my damage while in Clion I get the right ones.
I hope the code that I provided will help you to find the reason to this strange behaviour
I want to know how to fix this problem and how to avoid it in the near future. Thank you in advance
Main.cpp
#include <iostream>
#include <vector>
#include <ctime>
#include <string>
#include <algorithm>
#include "mob.h"
using namespace std;
int main()
{
//Random seed
srand(time(nullptr));
//Player Initialization
//Mobs Initialization
mob Skeleton{rand()%51+50, rand()%21+30, rand()%11, "Skeleton", rand()%11+10};
mob Zombie{rand()%101+100, rand()%11+10, rand()%21, "Zombie", rand()%11};
mob Spider{rand()%21+30, rand()%11+20, rand()%11, "Spider", rand()%21+50};
mob Creeper{rand()%16+5, rand()%51+50, 0, "Creeper", rand()%6};
//Array of mobs
vector <mob> mobs;
mobs.push_back(Skeleton);
mobs.push_back(Zombie);
mobs.push_back(Spider);
mobs.push_back(Creeper);
//Fight
int CurrentAttack = 0, n;
while (1 < mobs.size())
{
//Mobs order output
cout << endl << mobs[0].name << endl;
cout << "Choose who to attack:" << endl;
tryAgain: //In case if user typed wrong number
for (int q = 1; q < mobs.size(); q++)
{
cout << q << " - " << mobs[q].name << endl;
}
//Choose who to attack
cin >> n;
switch (n)
{
case 1:
{
mobs[0].Attack(CurrentAttack);
mobs[1].TakeHit(CurrentAttack);
mobs[1].Return();
break;
}
case 2:
{
if (n > mobs.size()-1)
{ printf("This enemy is already dead");
goto tryAgain;
}
mobs[0].Attack(CurrentAttack);
mobs[2].TakeHit(CurrentAttack);
mobs[2].Return();
break;
}
case 3:
{
if (n > mobs.size()-1)
{
cout << "This enemy is already dead" << endl;
goto tryAgain;
}
mobs[0].Attack(CurrentAttack);
mobs[3].TakeHit(CurrentAttack);
mobs[3].Return();
break;
}
default:
goto tryAgain;
}
if (mobs[n].Health() == 0)
{
//Remove dead mob
rotate(mobs.begin(),mobs.begin()+n+1,mobs.end());
mobs.pop_back();
}
else
{
//Rotate Vector for different mob to attack
rotate(mobs.begin(),mobs.begin()+1,mobs.end());
}
}
cout << "⣿⣿⣿⣿⡿⠟⠛⠛⠛⠛⠉⠉⠙⠛⠛⠿⢿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠿⠟" << endl << "⣿⣿⣯⣥⣤⣶⣶⣶⣶⣿⣿⣿⣿⣿⣿⣷⣾⣿⣿⣿⣿⣿⣿⣿⣏⣀⣀⣀⡀" << endl << "⣿⣿⣿⣿⣿⣿⣿⡿⠿⠛⠛⠻⠿⠟⠉⠉⠉⢻⣿⣿⣿⡿⠟⠋⣡⣼⣿⣿⣿⡄" << endl
<< "⣿⣿⣿⣟⣭⣤⣶⣶⣿⣿⠃⠀⠀⢀⣀⣤⣶⣿⣿⣿⣿⡅⡀⢀⣩⣤⣤⠀" << endl << "⣿⣿⣿⣿⣿⣿⣛⡛⠛⠛⠛⢋⣩⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣛⠛⠛⠓⠠" << endl << "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⣤⣤⣤⣦" << endl
<< "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇" << endl << "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠿⠿⠿⠿⢿⡿⢿⣿⣿⣿⠃" << endl << "⠿⠿⠿⠿⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣥⣄⣀⣀⠀⠀⠀⠀⠀⢰⣾⣿⣿⠏" << endl
<< "⠀⠀⠀⠀⠀⠀⠉⣩⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣤⣜⡻⠋" << endl << "⣰⣾⣷⣶⣿⣾⣖⣻⣿⣿⡿⣿⣿⣿⣿⠿⠿⠟⠛⠛⠛⠋⠉⠉⢉⡽⠃" << endl << "⣿⣿⣿⣿⣿⣿⡉⠉⠉⠛⠛⠛⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⡤⠚⠉" << endl
<< "⠛⠛⣿⣿⣿⣿⣿⣿⣿⠉⠛⢶⣶⣄⠀⠀⠀⠀⠀⠀⠀⠀⡇" << endl << "⠠⣾⣿⣿⣿⣿⣿⠿⠟⠃⠀⠀⠀⠈⠲⣴⣦⣤⣤⣤⣶⡾⠁" << endl << "⠄⠈⠉⠻⢿⣿⣿⡀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠛⠛⠛⠉⠀" << endl;
cout << endl << mobs[0].name << " has survived!" << endl;
return 0;
}
Mob.h
#ifndef TEXTRPG_MOB_H
#define TEXTRPG_MOB_H
#include <string>
#include <iostream>
using namespace std;
class mob {
int health;
int damage;
int armor;
int attack = 0;
int agility;
void Damage(int attack);
//Types of Attack
void StrongAttack(int& CurrentAttack);
void SmallAttack(int& CurrentAttack);
void Crit(int& CurrentAttack);
public:
string name;
void Return();
void GiveAttack(int& CurrentAttack);
void Attack(int& CurrentAttack);
void TakeHit(int attack);
bool Health();
mob(int health, int damage, int armor, string name, int agility);
};
#endif
Mob.cpp
#include "mob.h"
using namespace std;
//Attack function
void mob::Attack(int& CurrentAttack) {
int n;
cout << "Choose what attack to use:\n1 - Strong Attack;\n2 - Simple Attack;\n3 - Critical Strike;\n";
cin >> n;
switch (n) {
case 1:
StrongAttack(CurrentAttack);
break;
case 2:
SmallAttack(CurrentAttack);
break;
case 3:
Crit(CurrentAttack);
break;
default:
SmallAttack(CurrentAttack);
break;
}
}
//Types of Attack
void mob::StrongAttack(int& CurrentAttack)
{
this -> attack = damage*2;
mob::GiveAttack(CurrentAttack);
}
void mob::SmallAttack(int& CurrentAttack)
{
this -> attack = damage;
mob::GiveAttack(CurrentAttack);
}
void mob::Crit(int& CurrentAttack)
{
if (rand() % 2)
{
this -> attack = damage*3;
mob::GiveAttack(CurrentAttack);
};
}
//Share Attack to main.cpp
void mob::GiveAttack(int& CurrentAttack)
{
CurrentAttack = attack;
}
//TAKE HIT
//Take damage from other mob
void mob::TakeHit(int attack)
{
if (rand()%101 > agility)
{
Damage(attack);
}
else
{
this -> attack = 0;
cout << "You missed" << endl;
}
}
void mob::Damage(int attack) //Health calculation
{
//Damage Calculation
if (attack - armor <= 0)
this -> attack = 0;
else
this -> attack -= armor;
//Health calculation
if (health - attack <= 0)
{
cout << name << " is dead" << endl;
this -> health = 0;//Health < 0 -> Death
}
else
this -> health -= attack; //Health Calculation
}
//Public
void mob::Return()
{
cout << name << " took " << attack << " damage" << endl;
cout << name << " has " << health << " HP left" << endl;
}
bool mob::Health()
{
if (health == 0)
return 0;
else
return 1;
}
//Constructor
mob::mob(int health, int damage, int armor, string name, int agility)
{
this -> health = health;
this -> damage = damage;
this -> armor = armor;
this -> name = name;
this -> agility = agility;
}

Accessing variables in base class C++

Hi this is the header file for my base class Ranger, and in it I have protected variables fov_, usb_ ... that I wish to access with my getter functions, I have three child classes on this one.
Ranger.h
#ifndef RANGER_H
#define RANGER_H
using namespace std;
class Ranger
{
//private contructor prevents contruction of base class
Ranger();
public:
void setBaud(int baud);
virtual void setFOV(int fov) = 0;
void setSamp(int sam);
int getFOV();
int getBaud();
int getMaxRange();
int getUSB();
protected:
//protected variables that are each indivdualy owned by each sensor
int fov_;
int maxRange_;
int usb_;
int baud_;
int samp_;
double data[];
//protected contructors for the child classes to use to set fixed parameters
Ranger(int fov, int maxRange, int port);
Ranger(int maxRange, int port);
};
#endif // RANGER_H
This is my cpp file for the base class that includes the getter files, it just has a return of the portected variables.
Ranger::Ranger()
{
}
Ranger::Ranger(int fov, int maxRange, int port)
{
fov_ = fov;
maxRange_ = maxRange;
usb_ = port;
}
Ranger::Ranger(int maxRange, int port)
{
maxRange_ = maxRange;
usb_ = port;
}
void Ranger::setBaud(int baud)
{
switch(baud)
{
case 0: baud_ = 38400; break;
case 1: baud_ = 115200; break;
default: baud_ = 38400; break;
}
}
void Ranger::setSamp(int sam)
{
samp_ = sam;
}
int Ranger::getFOV()
{
return fov_;
}
int Ranger::getBaud()
{
return baud_;
}
int Ranger::getMaxRange()
{
return maxRange_;
}
int Ranger::getUSB()
{
return usb_;
}
And in my main I want to access the protected variables from the base class to prevent re writting code, so each childs variables are protected in the base class. I try to access these by las.getFOV() but I get a segmentation fault error meaning I don't have access to them, and I don't quite understand why.
main.cpp
int main( int argc, char ** argv)
{
Laser las;
int baud;
cout << "Baud:" << endl;
cout << "0 - 38400" << endl;
cout << "1 - 115200" << endl;
cin >> baud;
las.setBaud(baud);
cout << "Baud for Lazer sensor is "+las.getBaud() << endl;
cout << "Lazer sensor created..." << endl;
cout << "Lazer's FOV: " + las.getFOV() << endl;
cout << "Lazer's Max Range: " + las.getMaxRange() << endl;
cout << "Lazer's Port: " + las.getUSB() << endl;
Radar rad;
int baud2;
cout << "Baud:" << endl;
cout << "0 - 38400" << endl;
cout << "1 - 115200" << endl;
cin >> baud2;
rad.setBaud(baud2);
cout << "Baud for Radar sensor is "+rad.getFOV() << endl;
int fov;
cout << "Feild of View Of Radar:" << endl;
cout << "0 - 20 degrees" << endl;
cout << "1 - 40 degrees" << endl;
cin >> fov;
rad.setFOV(fov);
cout << "FOV is set to " + rad.getFOV() << endl;
cout << "Radar sensor created..." << endl;
cout << "Radar's FOV: ' " + rad.getFOV() << endl;
cout << "Radar's Max Range: " + rad.getMaxRange() << endl;
cout << "Radar's Port: " + rad.getUSB() << endl;
Sonar son;
//rad.setFOV(user);
}
and here is one of the child class's cpp file for reference (Lazer)
laser.cpp
#include "laser.h"
Laser::Laser() : Ranger(180,8,0)
{
};
void Laser::setFOV(int fov)
{
fov_ = fov;
}
laser.h
#ifndef LASER_H
#define LASER_H
#include "ranger.h"
#include "rng.h"
class Laser : public Ranger
{
public:
Laser();
void setFOV(int fov);
};
#endif // LASER_H
Thanks everyone who commented, I understand I put way too much code to help you guys out, sorry about that I'll know for next time, and thankyou to letting me know the difference between the errors, I've done more research and found that the issue was when I was printing it out you can't use operators like:
cout<<""+function()<<endl;
Instead you need to separate the functions from the array like so:
cout<<""<<function()<<endl;
Thanks guys.

C++ Using array and for loop to output from multiple classes

I am asked to do this code and i need to use array or something similar to print out different classes. The only way i know is individually doing every single class is there a faster way of doing this. Following is the way i am using at the moment.
Ground_Transport Gobj;
Air_Transport Aobj;
Sea_Transport Sobj;
Car Cobj;
Train Tobj;
Bus Bobj;
Gobj.estimate_time();
Gobj.estimate_cost();
cout << Gobj.getName() << endl;
Bobj.estimate_time();
Bobj.estimate_cost();
cout << Bobj.getName() << endl;
Sobj.estimate_time();
Sobj.estimate_cost();
cout<<Sobj.getName()<<endl;
Aobj.estimate_time();
Aobj.estimate_cost();
cout << Aobj.getName() << endl;
Cobj.estimate_time();
Cobj.estimate_cost();
cout << Cobj.getName() << endl;
Tobj.estimate_time();
Tobj.estimate_cost();
cout << Tobj.getName() << endl;
Transport_KL_Penang Kobj;
cout << Kobj.getName() << endl;
This is the header file Transport_KL_Penang
#include <iostream>
#include <string>
using namespace std;
class Transport_KL_Penang
{
public:
Transport_KL_Penang() {}
virtual string getName() {
return Name;
}
int Time_in_hours1 ;
int Time_in_hours2 ;
int Cost_in_RM1 ;
int Cost_in_RM2 ;
void estimate_time() ;
void estimate_cost() ;
private:
static string Name;
};
void Transport_KL_Penang::estimate_time()
{
cout << "It takes " << Time_in_hours1 << "-" << Time_in_hours2 <<
" hours if you use " << Name << endl;
}
void Transport_KL_Penang::estimate_cost()
{
cout << "It will cost around " << Cost_in_RM1 << "-" << Cost_in_RM2 <<
"RM if you use " << Name << endl;
}
If you don't need a specific object name, you can write something as a code below, creating a multiples generics objects:
#include <iostream>
#include <cstdlib>
#include <time.h>
class Myclass {
private:
int randTime;
float cost;
public:
void estimate_time(){
randTime = rand()%100;
}
void estimate_cost(){
cost = randTime * 0.2;
}
float getEstimateCost(){
return cost;
}
};
int main(){
srand(time(NULL));
int numberOfObjects = 7;
Myclass obj[numberOfObjects];
//input
for(int i = 0; i < numberOfObjects; i++){
obj[i].estimate_time();
obj[i].estimate_cost();
}
// printing
for(int i = 0; i < numberOfObjects; i++){
std::cout << obj[i].getEstimateCost() << std::endl;
}
return 0;
}

C++ Method won't call correct information from variable

I am working a a text adventure and have come across an error when I try to call a method from another method. The method returns the private int player_health and private int player_attack this work when I call it in main but when I call it in my combat_handler class it just give me a random number. I call it the exact same way in both class. Here is my code
Main.cpp
#include <iostream>
#include "player_handler.h"
#include "enemy_handler.h"
#include "combat_handler.h"
using namespace std;
int main()
{
cout << "Hello world!" << endl;
player_handler phobj;
enemy_handler ehobj;
combat_handler cbobj;
phobj.test_player_systems();
ehobj.test_enemy_stats();
cbobj.player_turn();
phobj.get_player_stats();
return 0;
}
player_handler header
#ifndef PLAYER_HANDLER_H
#define PLAYER_HANDLER_H
class player_handler
{
public:
player_handler();
int get_player_health();
int get_player_attack();
void get_player_stats();
void add_player_health(int x);
void remove_player_health(int x);
void add_player_attack(int y);
void set_player_stats(int x, int y);
int test_player_systems();
private:
int player_health;
int player_attack;
};
#endif // PLAYER_HANDLER_H
player_handler.cpp
#include "player_handler.h"
#include <iostream>
using namespace std;
player_handler::player_handler()
{
//cout << "working"<< endl;
}
//Getting the players stats
int player_handler::get_player_health()
{
return player_health;
}
int player_handler::get_player_attack()
{
return player_attack;
}
void player_handler::get_player_stats()
{
cout << "the players health is " << get_player_health()<<endl;
cout << "The players attack is " << get_player_attack() <<endl;
}
//setting the player stats
void player_handler::set_player_stats(int x, int y)
{
player_handler::player_health = x;
player_attack = y;
//cout << "player health is " << player_health << endl;
//cout << "player attack is " << player_attack << endl;
}
//Player health control
void player_handler::add_player_health(int x)
{
//cout << "The old player health was " << player_health << endl;
player_health = player_health + x;
//cout << "Your health is now " << player_health << endl;
}
void player_handler::remove_player_health(int x)
{
//cout << "you lost " << x << " health" << endl;
player_health = player_health - x;
//cout << "Your new health is " << player_health << endl;
}
//player attack control
void player_handler::add_player_attack(int y)
{
//cout << "Your attack has been upgraded by " << y << " points" << endl;
player_attack = player_attack+y;
//cout << "You attack is now " << player_attack <<endl;
}
//test all player systems
int player_handler::test_player_systems()
{
set_player_stats(10,10);
cout <<"The player health is " << get_player_health()<<endl;
cout <<"the player attack is " << get_player_attack() << endl;
add_player_health(5);
remove_player_health(5);
add_player_attack(5);
get_player_stats();
return 0;
}
Now keep in mind that all this works it returns the right value for player_health and player_attack. now here is my problem it just gives me a random number
combat_handler header
#ifndef COMBAT_HANDLER_H
#define COMBAT_HANDLER_H
class combat_handler
{
public:
combat_handler();
int player_turn();
int enemy_turn();
private:
int player_input;
int player_dmg_given;
int enemy_dmg_given;
};
#endif // COMBAT_HANDLER_H
combat_handler.cpp
#include "combat_handler.h"
#include <iostream>
#include "player_handler.h"
using namespace std;
combat_handler::combat_handler()
{
cout << "combat handler on-line\n";
}
int combat_handler::player_turn()
{
player_handler phobj;
cout << "Would you like to (1)check stats (2) Enter the room?\n";
cin >> player_input;
switch(player_input){
case 1:
cout << "one"<<endl;
phobj.get_player_stats();
break;
default:
cout << "entering the room.\n";
break;
}
return 0;
}
The error happens when I call get_player_stats from the phobj in the combat handler class.
player_handler phobj;
This would call default constructor for player_handler( from your code it seems you are doing nothing in default constructor). And then you are calling get_player_stats() without setting the values. So, it would surely give you random values.
Earlier in main,
phobj.test_player_systems(); <<<< This is setting values.
phobj.get_player_stats(); <<<< Then you are querying on values already set.

How to Initialize objects with overloaded constructors using different files

I have tried literally everything to try to initialize the constructor so that when I create an object and pass the parameters in, it wont give me a crazy negative number, but it's still not working!
To test that it works I used the getHp and attack function. So for example, if I say Hero Hi(100, 200, 300, 400), then I say Hi.getHP(), it should be 100(the first parameter)...
//main.cpp
int main()
{
Hero Me(100,20,30,40);//Created using overloaded constructor
Monsters m(100,16,18,20);//creates a monster object and uses overloaded constructor
to initialize
cout << "\ntest1\n";
Me.getHp();//expecting 100
Me.getAttack();//expecting w.e is in parameters
m.getHp();//expecting 100
m.getAttack();//same as hero
cin.sync();
cin.get();
return 0;
}
Here is the rest of my code, in case you need it. I also left out headers and such for simpler code.
//Characters.h
class Characters
{
private:
int level;
int hp;
int attack;
int defense;
protected:
Characters(); // zero everything by default
Characters(int, int, int, int); // populate explicitly
~Characters();
public:
int getAttack() const { return attack; }
int getDefense() const { return defense; }
int getHp() const { return hp; }
int getlevel() const { return level; }
void setAttack(int);
void setDefense(int);
void setStrength(int);
void setHp(int);
void setlevel(int);
void damageTaken(int);
};
//Characters.cpp
Characters::Characters() : level(0), hp(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){}
Hero::Hero(int newHp, int newLevel, int newAttack, int newDef)
: Characters(newHp, newLevel, newAttack, 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;
// logging goes here
// note that you don't need HeroLevel etc. at all any more, just use level
}
Monsters::Monsters(int newHp, int newLevel, int newAttack, int newDef)
: MonsterHp(newHp), Monsterlevel(newLevel), MonsterAttack(newAttack)
, MonsterDefense(newDef)//initialize list
{
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;
}
Characters::~Characters()
{
cout << "Character has been destroyed!\n";
}
void Characters::setAttack(int att)
{
attack = att;
}
void Characters::setDefense(int def)
{
defense = def;
}
void Characters::setHp(int health)
{
hp = health;
}
void Characters::damageTaken(int damage)
{
hp -= damage;
}
void Characters::setlevel(int lvl)
{
level = lvl;
}
//Monsters.h
class Monsters:
public Characters //Hero
{
private:
int Monsterlevel;
int MonsterHp;
int MonsterStrength;
int MonsterAttack;
int MonsterDefense;
public:
Monsters(int, int, int, int); //explicit
~Monsters();
};
//Monsters.cpp
Monsters::~Monsters()
{
cout << "\nMonster Destroyed";
}
//Hero.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
Hero::~Hero()
{
cout << "Hero destroyed!\n";
}
HeroHp in the Hero class and hp in the Characters class are separate variables. The constructor for Hero never intializes hp, which is the variable that is returned by getHp.
You probably want to eliminate the HeroXXX variables in the Hero class and use the corresponding ones in the Characters base class.
It works fine if I uncomment Characters constructor: http://coliru.stacked-crooked.com/view?id=261944b9b1304c3ed9d76e69b2318ee2-ad7854d9cfd7979d567ca413f0830b65
Are you sure you were compiling with success? You left some warnings around that might have deceived you... A very good reason for removing always all of your warnings.