In C++, how do I access declared objects across multiple class files? - c++

I didn't include a Player.h file or .cpp file since they're exactly the same as my Monster.h and .cpp file.
I'm making a game and I created a player object in my Login.cpp file that takes the username and an int as the parameters. Is there a way to access the object's parameters in my BattleStats() function within my BattleSystem.cpp file? My goal is to eventually update the parameters as the player gets hit by the monster and to output those updated parameters.
Here's my code, thank you for the help:
Main.cpp
#include "Login.h"
#include "GameManager.h"
#include "BattleSystem.h"
#include <iostream>
using namespace std;
int main() {
BattleSystem bs;
GameManager gm(&bs);
Login login(&gm);
login.StartMenu();
cout << "ENDING" << endl;
system("pause"); //Pause console.
return 0; //Terminated without errors.
}
Login.h
#pragma once
#include "GameManager.h"
#include <iostream>
using namespace std;
class Player;
class GameManager;
class Login {
public:
Login(GameManager* gmPtr) : manager(gmPtr) {}
void StartMenu();
private:
string username = "Kujo";
Player* player;
GameManager* manager;
};
Login.cpp
#include "Login.h"
#include "Player.h"
#include "GameManager.h"
void Login::StartMenu() {
player = new Player(username, 100);
manager->GameStart();
}
GameManager.h
#pragma once
class BattleSystem;
class GameManager {
public:
GameManager(BattleSystem* bsPtr) : battle(bsPtr) {}
void GameScenario();
private:
int level = 1;
BattleSystem* battle;
};
GameManager.cpp
#include "BattleSystem.h"
#include "Login.h"
#include "GameManager.h"
void GameManager::GameScenario() {
battle->Encounter();
}
BattleSystem.h
#pragma once
class Player;
class Monster;
class BattleSystem {
public:
void Encounter();
void BattleStats();
private:
Monster* monster;
Player* player;
};
BattleSystem.cpp
#include "Player.h"
#include "Monster.h"
#include "BattleSystem.h"
void BattleSystem::Encounter() {
monster = new Monster("Mini Orc", 100);
cout << "A " << monster->GetName() << " has appeared!" << endl;
BattleStats();
}
void BattleSystem::BattleStats() {
cout << "Monster name: " << monster->GetName() << endl;
cout << "Monster HP: " << monster->GetHP() << endl << endl;
cout << "Player name: " << "PLAYER NAME HERE" << endl;
cout << "Player HP: " << "PLAYER HP HERE" << endl << endl;
}
Monster.h
#pragma once
#include <string>
#include <iostream>
using namespace std;
class Monster {
public:
Monster();
Monster(string monsterName, int health);
void SetName(string monsterName);
void SetHP(int health);
string GetName() const;
int GetHP() const;
private:
string name = "Monster";
int healthPoints = 0;
};
Monster.cpp
#include "Monster.h"
Monster::Monster() : name("Player"), healthPoints(0) {}
Monster::Monster(string monsterName, int health) {
name = monsterName;
healthPoints = health;
}
void Monster::SetName(string monsterName) {
name = monsterName;
}
void Monster::SetHP(int health) {
healthPoints = health;
}
string Monster::GetName() const {
return name;
}
int Monster::GetHP() const {
return healthPoints;
}

Try to insert friend BattleSystem to your Player class.
Then you will have an access to private fields of Player from BattleSystem.

Related

Undefined Symbol in inherited classes for member Functions C++

So I'm writing a Manager class which inherits from SalariedEmployee which inherits from Employee. I have the employee.h header file and employee.cpp header file and also for salariedemployee as shown below.
I cant seem to understand why I get the following errors when I try to compile the code of
Undefined symbol: employeessavitch::SalariedEmployee::SalariedEmployee()
Undefined symbol: employeessavitch::SalariedEmployee::SalariedEmployee()
Undefined symbol: employeessavitch::SalariedEmployee::get_salary() const
Undefined symbol: employeessavitch::Employee::get_ssn() const
Undefined symbol: employeessavitch::Employee::get_name() const
Here are my files
employee.h
#ifndef employee_h
#define employee_h
#include <string>
#include "employee.h"
using namespace std;
namespace employeessavitch
{
class Employee
{
public:
Employee();
Employee(string the_name, string the_ssn);
string get_name( ) const;
string get_ssn( ) const;
double get_net_pay( ) const;
void set_name(string new_name);
void set_ssn(string new_ssn);
void set_net_pay(double new_net_pay);
void print_check( ) const;
protected:
string name;
string ssn;
double net_pay;
};
}
#endif /* employee_h */
employee.cpp
#include <string>
#include <cstring>
#include <stdio.h>
#include <cstdlib>
#include <iostream>
#include "employee.h"
using namespace std;
namespace employeessavitch
{
Employee::Employee(): name("No name yet"), ssn("No number yet"), net_pay(0)
{
//deliberately empty
}
Employee::Employee(string the_name, string the_ssn)
{
//deliberately empty
}
Employee::Employee(string the_name, string the_number): name(the_name), ssn(the_number), net_pay(0)
{
//deliberately empty
}
string Employee::get_name() const
{
return name;
}
string Employee::get_ssn() const
{
return ssn;
}
double Employee::get_net_pay() const
{
return net_pay;
}
void Employee::set_name(string new_name)
{
name = new_name;
}
void Employee::set_ssn(string new_ssn)
{
ssn = new_ssn;
}
void Employee::set_net_pay (double new_net_pay)
{
net_pay = new_net_pay;
}
void Employee::print_check( ) const
{
cout << "\nERROR: print_check FUNCTION CALLED FOR AN \n"
<< "UNDIFFERENTIATED EMPLOYEE. Aborting the program.\n"
<< "Check with the author of the program about this bug.\n";
exit(1);
}
}//employeessavitch
salariedemployee.h
#ifndef salariedemployee_h
#define salariedemployee_h
#include <string>
#include "employee.h"
#include "salariedemployee.h"
namespace employeessavitch
{
class SalariedEmployee : public Employee
{
public:
SalariedEmployee();
SalariedEmployee (string the_name, string the_ssn, double the_weekly_salary);
double get_salary() const;
void set_salary(double new_salary);
void print_check();
protected:
double salary;//weekly
};
}//employeessavitch
#endif /* salariedemployee_h */
salariedemployee.cpp
#include <iostream>
#include <string>
#include <stdio.h>
#include "salariedemployee.h"
using namespace std;
namespace employeessavitch
{
SalariedEmployee::SalariedEmployee() //: Employee(), salary(0)
{
//deliberately empty
}
SalariedEmployee::SalariedEmployee(string the_name, string the_number, double the_weekly_salary)//: Employee(the_name, the_number), salary(the_weekly_salary)
{
//deliberately empty
}
double SalariedEmployee::get_salary() const
{
return salary;
}
void SalariedEmployee::set_salary(double new_salary)
{
salary = new_salary;
}
void SalariedEmployee::print_check()
{
set_net_pay(salary);
cout << "\n__________________________________________________\n";
cout << "Pay to the order of " << get_name( ) << endl;
cout << "The sum of " << get_net_pay( ) << " Dollars\n";
cout << "_________________________________________________\n";
cout << "Check Stub NOT NEGOTIABLE \n";
void SalariedEmployee::print_check()
{
set_net_pay(salary);
cout << "\n__________________________________________________\n";
cout << "Pay to the order of " << get_name( ) << endl;
cout << "The sum of " << get_net_pay( ) << " Dollars\n";
cout << "_________________________________________________\n";
cout << "Check Stub NOT NEGOTIABLE \n";
cout << "Employee Number: " << get_ssn( ) << endl;
cout << "Salaried Employee. Regular Pay: "
<< salary << endl;
cout << "_________________________________________________\n";
}
}//employeessavitch
main.cpp
#include <iostream>
#include <cstring>
#include <string>
#include <string.h>
#include <fstream>
#include "salariedemployee.h"
#include "employee.h"
using namespace std;
namespace employeessavitch
{
class Manager: public SalariedEmployee
{
public:
Manager();
~Manager();
void addReport(SalariedEmployee employee);
friend ostream& operator <<(ostream &outs, Manager manager);
private:
SalariedEmployee *reports;
int noReport;
};
Manager::Manager()
{
noReport = 0;
}
Manager::~Manager()
{
delete[] reports;
}
void Manager::addReport(SalariedEmployee employee)
{
SalariedEmployee *report = new SalariedEmployee[noReport+1];
for(int i = 0; i < noReport; i++)
{
report[i] = reports[i];
}
report[noReport+1] = employee;
delete[] reports;
}
ostream& operator <<(ostream &outs, Manager manager)
{
for(int i = 0; i < manager.noReport; i++)
{
outs << manager.reports[i].get_name() << endl;
outs << manager.reports[i].get_ssn() << endl;
outs << manager.reports[i].get_salary() << endl;
}
return outs;
}
}
int main()
{
cout << "hello world";
return 0;
}

object is undefined in function

Im new to C++ and started working with classes recently for a school excercice.
I really cant see whats wrong and after creating an object "player" to the Hero class i can't use that object later in the "main Menu" function to call a method because i get the "identifier is undefined" error!
Any suggestions?
#include "stdafx.h"
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
class Hero
{
private:
//member variables
string playername;
public:
//constructor
Hero(string name)
{
playername = name;
}
string getName()
{
return playername;
}
};
//start 1
void mainMenu()
{
cout << " - - - |" << player.getName() << "- - - \n";
}
void setPlayer()
{
string name;
cout << "Hello, what is your name? " << endl;
getline(cin, name);
Hero player(name);
mainMenu();
}
int main()
{
int selection;
cout << "Shadow of darkness\n ";
cout << "1.) Start ";
cout << "2.) Exit ";
cin >> selection;
if (selection == 1)
setPlayer();
else if (selection == 2)
exit (0);
else
main();
return 0;
}
OK, calling main() from main() is a forbidden (as explained here), so do not do it.
Here is a typical example with your class (the class is cool as you have it, I just added an initializer list for fun):
#include <iostream>
#include <string>
using namespace std;
class Hero
{
private:
//member variables
string playername;
public:
//constructor
Hero(string name) : playername(name)
{
}
string getName()
{
return playername;
}
};
int main()
{
Hero player("Daniel");
cout << "Player's name: " << player.getName() << std::endl;
return 0;
}
Output:
Player's name: Daniel
Based on this, try to work your logic and do all sort of stuff that you long for (after reading some books/tutorials)!

LNK1169 "one or more multiply defined symbols found" in a basic game

This project is not done but currently my group is stuck with the LNK1169 error.
We have a player.h and player.cpp as well as an enemy.h and enemy.cpp and obviously a source.cpp. Somehow the linking between the files got messed up when we combined work on the player and work on the enemy files.
Source.cpp
//#pragma once
#include "Player.h"
#include "Enemy.h"
#include <iostream>
#include <fstream>
#include <string>
#include <time.h>
#include <random>
using namespace std;
int main()
{
cout << "Welcome to our game" << endl;
cout << endl << endl << endl;
int ans = 0;
do {
cout << " Main Menu" << endl;
cout << "-----------------------------" << endl;
cout << "1: Play Game" << endl;
cout << "-----------------------------" << endl;
cout << "2: Exit" << endl;
cout << "-----------------------------" << endl;
cin >> ans;
switch (ans)
{
case 1: //main body of game
case 2:
return 0;
default:
cout << "Please enter 1 to play the game or 2 to exit" << endl;
cin >> ans;
break;
}
} while (ans != 2);
return 0;
}
Enemy.h:
/* UML
Enemies
******************************************
Private
- Health: int
- Attack : int
- Defence : int
******************************************
Public
+ accessor and mutator functions
+ AttackCharacter()
+ DefendCharacter()
+ ChangePosition()
+ LoseHealth()
+ RandomSpawn()
*******************************************
*/
//#pragma once
#ifndef PLAYER_H
#define PLAYER_H
#include <iostream>
#include <string>
using namespace std;
class Enemy
{
private:
int
health,
attack,
defence;
public:
Enemy(int Health, int Attack, int Defence)
{
health = Health; attack = Attack; defence = Defence;
}
int getHealth();
int getAttack();
int getDefence();
void setHealth(int h);
void setAttack(int a);
void setDefence(int d);
//void Attack(Player P1);
};
#endif
Enemy.cpp
#include "Enemy.h"
#include "Player.h"
/*#include <iostream>
#include <string>
using namespace std;
*/
int Enemy::getHealth() { return health; }
int Enemy::getAttack() { return attack; }
int Enemy::getDefence() { return defence; }
void Enemy::setHealth(int h)
{
health = h;
}
void Enemy::setAttack(int a)
{
attack = a;
}
void Enemy::setDefence(int d)
{
defence = d;
}
//void Enemy::Attack(Player P1)
//{
// int h = P1.getHealth();
// int d = P1.getDefence();
// int a = getAttack();
// if (d + h - a > h)
// {
// cout << "You lost 0 health" << endl;
// P1.setHealth(h);
// }
// else
// {
// int h1 = h + d - a;
// cout << "You lost " << h1 - h << " health" << endl;
// P1.setHealth(h1);
// }
//}
The Enemy::attack() function is a work in progress and not really the problem
Player.h:
//#pragma once
#ifndef PLAYER_H
#define PLAYER_H
#include <iostream>
#include <vector>
#include <string>
using namespace std;
struct Armor
{
string name;
char type;
int health;
int attack;
int defense;
Armor() { name = ""; type = ' '; health = 0; attack = 0; defense = 0; } // constructor
};
struct Weapon
{
string name;
char type;
int health;
int attack;
int defense;
Weapon() { name = ""; type = ' '; health = 0; attack = 0; defense = 0; } // constructor
};
struct Shield
{
string name;
char type;
int health;
int attack;
int defense;
Shield() { name = ""; type = ' '; health = 0; attack = 0; defense = 0; } // constructor
};
struct Potion
{
string name;
char type;
int health;
int attack;
int defense;
Potion() { name = ""; type = ' '; health = 0; attack = 0; defense = 0; } // constructor
};
vector<string> type = { "Bronze", "Iron", "Silver", "Steel", "Gold", "Diamond" };
class Player
{
private:
string name;
int initialhealth;
int initialattack;
int initialdefense;
int health;
int attack;
int defense;
public:
Player(string n = " ", int ih = 0, int ia = 0, int id = 0, int h = 0, int a = 0, int d = 0)
{
name = n; initialhealth = ih; initialattack = ia; initialdefense = id; health = h; attack = a; defense = d;
};
Armor armor;
Weapon weapon;
Shield shield;
Potion potion;
string getname();
int getinitialhealth();
int getinitialattack();
int getinitialdefense();
int getHealth();
int getAttack();
int getDefense();
void setname(string n);
void setinitialhealth(int ih);
void setinitialattack(int ia);
void setinitialdefense(int id);
void setHealth(int h);
void setAttack(int a);
void setDefense(int d);
void addITEMS();
void displayPlayer();
void checkARMOR();
};
#endif
Player.cpp:
//#include <iostream>
//#include <string>
#include "Player.h"
//using namespace std;
string Player::getname() { return name; }
int Player::getinitialhealth() { return initialhealth; }
int Player::getinitialattack() { return initialattack; }
int Player::getinitialdefense() { return initialdefense; }
int Player::getHealth() { return health; }
int Player::getAttack() { return attack; }
int Player::getDefense() { return defense; }
void Player::setname(string n) { name = n; }
void Player::setinitialhealth(int ih) { initialhealth = ih; }
void Player::setinitialattack(int ia) { initialattack = ia; }
void Player::setinitialdefense(int id) { initialdefense = id; }
void Player::setHealth(int ih) { health = ih; }
void Player::setAttack(int ia) { attack = ia; }
void Player::setDefense(int id) { defense = id; }
void Player::addITEMS()
{
health = initialhealth + armor.health + weapon.health + shield.health;
attack = initialattack + armor.attack + weapon.attack + shield.attack;
defense = initialdefense + armor.defense + weapon.defense + shield.defense;
}
void Player::displayPlayer()
{
cout << endl;
cout << "=========================" << endl;
cout << " Name : " << name << endl;
cout << " Health : " << health << endl;
cout << " Attack : " << attack << endl;
cout << " Defence : " << defense << endl;
cout << "=========================" << endl;
}
void Player::checkARMOR()
{
if (weapon.name == "Bronze")
{
armor.health = 10;
armor.attack = 5;
armor.defense = 15;
}
if (armor.name == "Iron")
{
armor.health = 100;
armor.attack = 15;
armor.defense = 150;
}
}
Any insight anyone could give into why the LNK1169 error may be popping up would be greatly appreciated. Thank you.
Its simple, you have used
#ifndef PLAYER_H
#define PLAYER_H
twice in Player.h and Enemy.h. Just simply replace:
#ifndef PLAYER_H
#define PLAYER_H
by
#ifndef ENEMY_H
#define ENEMY_H
in Enemy.h
Or use #pragma once preprocessor directive before your declarations in *.h
files
But the real problem is this line in Player.h
std::vector<std::string> type = { "Bronze", "Iron", "Silver", "Steel", "Gold", "Diamond" };
To declare an global variable in a header use the keyword extern.
// Player.h
extern std::vector<std::string> type;
// Player.cpp
std::vector<std::string> type = { "Bronze", "Iron", "Silver", "Steel", "Gold", "Diamond" };
Is it not an option to change this to an enum class?
enum class Types {
Bronze,
Iron,
Silver,
Steel,
Gold,
Diamond
};
And use namespace through out the application?

Class Header , string does not name a type

Hi I'm trying to finish my homework. I have a compilation error when I try to separate a class, then call it later. But the whole test function works properly. It has the class within the whole text. Basically when i try to separate the class from the text, I have an error message.
#include <iostream>
#include<string>
using namespace std;
class Person
{
private:
string alpha;
int beta;
public:
Person(string Name, int Age)
{
alpha = Name;
beta = Age;
}
string getName()
{
return alpha;
}
int getAge()
{
if (beta < 0)
{ beta = 0;
cout << "Error. A negative age cannot be entered. " << endl;
}
if (beta > 120)
{
cout << "Damn you're old. How many heart transplants have you had? You Vampire " << endl;
}
return beta;
}
void setName(string alpha)
{
}
void setAge(int beta);
void display();
};
int main()
{
Person Lu("Jess ", 22);
Person Rose("Gary ", 49);
cout << Lu.getAge() << " " << Lu.getName() <<endl;
cout << Rose.getAge() << " " << Rose.getName() << endl;
return 0;
}`
But when i separate the class,:
#include <iostream>
#include <string>
class Person
{
private:
string alpha;
int beta;
public:
Person(string Name, int Age)
{
alpha = Name;
beta = Age;
}
string getName()
{
return alpha;
}
int getAge()
{
if (beta < 0)
{ beta = 0;
cout << "Error. A negative age cannot be entered. " << endl;
}
if (beta > 120)
{
cout << "Damn you're old. How many heart transplants have you had? You Vampire " << endl;
}
return beta;
}
void setName(string alpha)
{
}
void setAge(int beta);
void display();
};
Main file
#include <iostream>
#include "Person.h"
#include <string>
using namespace std;
int main()
{
Person Lu("Jess ", 22);
cout << Lu.getAge() << " " << Lu.getName() <<endl;
return 0;
}`
But when I separate the class i get an error in codeblocks. Please help.
You forgot to put using namespace std; in Person.h.
Also, you don't have any header guards on Person.h, which won't cause a problem in such a simple program, but will as soon as multiple files include Person.h.

Friend function strange behaviour

I'm learning C++ by myself and one of the programs that I made is sort of a school information system, it is not my first OOP program but this time I experience some strange behavior of a friend function.
I have a derived class Student which has a private member - static array of Courses objects, and finally the main container class Class which has a member - dynamic array of Students objects.
as you can see avg member of student is calculated using a friend function of Courses class (calc_avg receives an array of Courses sums it's grades and divides by course number), it works like a charm.
The problem starts once I try to calculate an average grade (class_avg) for a Class object - I use the same logic - create a friend function of Student (class_avarage that will have access to each students avg) that will receive an array of Student objects and it's size, add each students average grade and divide by array size - for some reason it receives and returns garbage values, I've been trying to fix it for 3 hours and I cant find the problem, help me if you can - here is the relevant code (independent derived classes are not included and output functions are minimized):
main //only container object creation and IO functions (all .h files included)
Class test1;
test1.input_class();
test1.output_class();
Student.h
#include "Person.h"
#include "Courses.h"
#ifndef STUDENT_H
#define STUDENT_H
class Student : public Person
{
public:
Student();
void input_student ();
void output_student ();
friend float class_avarage (Student* array, int);
~Student();
protected:
private:
Courses my_courses [6];
float avg;
};
#endif // STUDENT_H
Student.cpp
#include "Student.h"
Student::Student()
{
//ctor
}
void Student::input_student ()
{
cout << "Please enter students info:" << endl;
input_info();
my_courses[0].input_grades ("Math");
my_courses[1].input_grades ("English");
my_courses[2].input_grades ("Science");
my_courses[3].input_grades ("History");
my_courses[4].input_grades ("Art");
my_courses[5].input_grades ("Sports");
}
void Student::output_student ()
{
int i;
cout << "Students info:" << endl;
output_info();
cout << " Course Grade" << endl;
for (i = 0; i < 6; i++)
{
my_courses[i].output_grades ();
}
avg = calc_avg(my_courses, 6);
cout << " " << "Average grade for student: " << avg << endl;
}
Student::~Student()
{
//dtor
}
float calc_avg (Courses* array, int size)
{
int i;
float sum = 0;
for (i = 0; i < size; i++)
{
sum += array[i].grade;
}
return sum/size;
}
Courses.h
#include <iostream>
#include <iomanip>
#include <string>
#ifndef COURSES_H
#define COURSES_H
using std::cout;
using std::cin;
using std::endl;
using std::string;
class Courses
{
public:
Courses();
void input_grades(string);
void output_grades();
friend float calc_avg (Courses*, int);
~Courses();
protected:
private:
string course_name;
int grade;
};
#endif // COURSES_H
Courses.cpp
#include "Courses.h"
Courses::Courses() : course_name ("Default"), grade (-1)
{
//ctor
}
void Courses::input_grades (string temp_name)
{
course_name = temp_name;
cout << "Enter " << temp_name << " grade: ";
cin >> grade;
cin.get();
}
void Courses::output_grades ()
{
cout << " " << course_name << ": " << grade << endl;
}
Courses::~Courses()
{
//dtor
}
Class.h
#include <iostream>
#include <string>
#include "Teacher.h"
#include "Student.h"
#ifndef CLASS_H
#define CLASS_H
using std::cout;
using std::cin;
using std::endl;
using std::string;
class Class
{
public:
Class();
void input_class ();
void output_class ();
~Class();
protected:
private:
string class_name;
Teacher class_teacher;
Student* pupils;
int students_number;
float class_avg;
};
#endif // CLASS_H
Class.cpp
#include "Class.h"
Class::Class() : class_name ("A"), pupils (NULL), students_number (0), class_avg (0)
{
//ctor
}
void Class::input_class ()
{
int i;
//input class data
cin >> students_number;
cin.get();
pupils = new (std::nothrow) Student [students_number];
if (!pupils)
{
cout << "Allocation failed!" << endl;
}
else
{
for (i = 0; i < students_number; i++)
{
pupils[i].input_student();
}
}
class_avg = class_avarage (pupils, students_number);
}
void Class::output_class ()
{
int i;
cout << " Displaying info of class :" << class_name << endl <<
" Class average grade: " << class_avg << endl;
class_teacher.output_teacher();
cout << " Number of students: " << students_number << endl << " Students: " << endl;
for (i = 0; i < students_number; i++)
{
pupils[i].output_student();
}
}
Class::~Class()
{
//dtor
}
float class_avarage (Student* array, int size)
{
cout << size << endl;
int i;
float total = 0;
for (i = 0; i < size; i++)
{
total += array[i].avg;
}
return total/size;
}
Why should anyone want to use friend functions? Just add simple getter for Cource.grade member and lasy getter for Student.avg. This will eliminate the possibility to get garbage instead of data.
Also, use std::vector and pass them throught std::vector&, not arrays and pointers.