I'm trying to make a very simple text-based game and I encountered an error when I tried to access a dynamic struct from an external function. I initialized all variables and structs in my header file and declared a dynamic alloc in the main function. But still I got errors. Am I missing something? This is my code.
==================main function "new.cpp"====================
#include <stdlib.h>
#include <iostream>
#include <string>
#include "game.h"
using namespace std;
difficulty _df_1;
player* player_1 = new player[3];
int main()
{
//initialize player stats
player_1->hp = 100;
player_1->life = 3;
player_1->mana = 50;
player_1->player_id = 1;
player_1->level = 1;
player_1->player_name= "emmet";
//..end
int turn=1;
cout << "What is your name? <<<";
getline(cin,player_1->player_name,'\n');
cout << "Choose a difficulty level: [0]Easy [1]Normal [2]Godlike" << endl;
int ch;
cin >> ch;
switch(ch)
{
case 0:
cout << "Scardy Cat chose EASY." << endl;
break;
case 1:
cout << "A really nice way to start. NORMAL" << endl;
break;
case 2:
cout << "Overly Manly Man is playing GODLIKE." << endl;
break;
default: cout << "I wonder how you can play this game if you can even read simple instructions."<< endl;return 0; break;
}
while(turn == 1)
{
char ch;
cout << "What do you want to do now? \n <<<<";
cin >> ch;
cin.ignore(5,'\n');
switch(ch)
{
case 'a': case 'A':
player_stat();
break;
case 'v': case 'V':
cheat_menu();
break;
case 'x': case 'X':
return 0;
break;
case '`':
break;
default: cout << "We were unable to process your request. Please try again" << endl; break;
}
}
delete player_1;
return 0;
}
void cheat_menu()
{
cout << "CHEATERS WILL ROT IN THE DEEPEST DEPTHS OF TARTARUS." << endl;
cout << "Enter Code:" << endl;
string cheat;
getline(cin,cheat,'\n');
if(cheat == "poo")
{
system("sleep 3");
cout << "Cheat Activated.." << endl;
player_1->hp += 1000;
player_1->level += 10;
player_1->mana += 1000;
player_stat();
}
else
{
cout << "Wrong cheat code.." << endl;
}
//system("sleep 3");
//system("clear");
}
==================end main function==============
=======external func "player_stat.cpp"===========
#include <iostream>
#include "game.h"
using namespace std;
void player_stat()
{
cout << "Name: " << player_1->player_name << endl
<< "Hp: " << player_1->hp << endl
<< "Life: " << player_1->life << "\t Mana: " << player_1->mana << endl
<< "Level: " << player_1->level << "\t XP: " << player_1->xp
<< endl;
//system("sleep 3");
//system("clear");
}
==================end external func==============
==========header file "game.h"===================
#ifndef _GAME_
#define _GAME_
#include "player_stat.cpp"
using namespace std;
//function prototypes...
void player_stat();
void cheat_menu();
//structs for player and NPC
struct player
{
string player_name;
int life;
double atk;
double hp;
double mana;
int player_id;
int level;
long int xp;
string weapon_name;
double weapon_damage;
};
enum difficulty {EASY,NORMAL,GODLIKE};
#endif
===========end header file=======================
These are the errors I got. Please don't mind the other left out functions in int main(). :P
In file included from game.h:4
from new.cpp
in function `void player_stat()':
`player_1' undeclared (first use in this function)
(Each undeclared identifier is reported only once for each function it appears in.)
At global scope:
`player*player_1' used prior to declaration
You declare the variable using the extern storage specifier:
extern player* player_1;
This tells the compiler that the player_1 variable is defined somewhere else, and the linker will resolve it later.
Also as I noted you actually allocate three player objects. If you only need one then don't allocate three:
player* player_1 = new player;
However, that's not needed either, declaring a normal non-pointer variable will work just as fine:
player player_1;
Then in the other files you use extern to tell the compiler that the variable is defined somewhere else:
extern player player_1;
add
extern player* player_1;
to game.h
this will make the player_1 variable available across all the modules.
also remove
#include "player_stat.cpp"
you are not supposed to include any cpp files in the header files
Related
I am completely new to programming and I am learning C++. I wrote a code to practice Functions with Return Values. The code builds and runs, but there is an error message and I would like some help understanding it.
#include <iostream>
using namespace std;
void showMenu() {
cout << " 1. Change personal information." << endl;
cout << " 2. Search a Record." << endl;
cout << " 3. Delete a Record." << endl;
cout << " " << endl;
}
int getInput() {
cout << "Please select a menu item: " << flush;
int menuNum;
cin >> menuNum;
return menuNum;
}
void processSelection (int options){
int password = 12;
int record = 4;
int record2 = 5;
switch (options) {
case 1:
...
}
int main() {
cout << "" << endl;
showMenu();
int menuSel = getInput();
processSelection (selection);
return 0;
}
I left out all the switch stuff because it takes up so much room.
The error is in int main () at processSelection (selection); It says "Type 'processSelection' could not be resolved."
Thank you
You passed undeclared identifier selection to processSelection function.
Just pass menuSel to processSelection, so your main should look like this:
int main() {
cout << "" << endl;
showMenu();
int menuSel = getInput();
processSelection(menuSel);
return 0;
}
So, my assignment in class was to make a C++ program that essentially makes a database with a number of options (adding to it, deleting entries, modifying, searching and listing). It has to be done specifically with arrays, not vectors or classes or whatever.
I decided to make a number of functions to handle each option, and have them all call each other. After extensive googling, I also decided to let a struct handle the declarations so I can use them in all functions without using :: marks. I specifically made everything depend on each other because the teacher hinted that we're going to have to do further work with it, so if I modify something, everything else changes to accommodate.
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
using namespace std;
struct va{
public:
int i, j, k, l; //for possible loops or variables I only need for a very short time
int id = 0;
int name = id+1;
// like 6 other ints I also declared here, including year2
int achi = year2+1;
//The above is for easier identification of pro[whatever][needed data]. The +1 method is to allow for easier editing later.
int size = 20, row = 0; //This is important for addition
string searchterm = ""; //this is for searching
public:
int main();
void MainMenu();
void Addition();
void Deletion();
void Search();
void Modify();
void List();
};
void MainMenu();
void Addition();
void Deletion();
void Search();
void Modify();
void List();
//I just find it neater to make side functions after the main one.
int main()
{
setlocale(LC_ALL, "");
const int column = achi;
const int initsize = size; //These two are so I can edit the size of the array from the struct directly
string pro[initsize][column]; //This creates the array that's the actual database
cout << endl << "Welcome to the League of Legends Pro Players database!" << endl << endl;
cout << endl << "Please, use the menu to access its functions.";
MainMenu();
cout << endl;
return 0;
}
void MainMenu()
{
cout << endl << "Main Menu" << endl;
cout << endl << "1: add an entry to the database.";
cout << endl << "2: delete an existing entry from the database.";
cout << endl << "3: search for an existing entry in the database.";
cout << endl << "4: modify an existing entry.";
cout << endl << "5: list all existing entries." << endl;
cin >> i;
switch(i)
{
case 1: Addition();
case 2: Deletion();
case 3: Search();
case 4: Modify();
case 5: List();
}
}
(I haven't written the actual functions for options yet.) However, when I tried to run it, I was told 'achi' wasn't declared in main, although I made everything public just so I won't run into this error. How could I make main "see" the struct and its variables?
You have only defined a type, you don't have an values of that type. You have also declared but not defined a number of member functions, and then declared (and presumably defined, tho many are not shown) free functions with the same names.
When providing out-of-class definitions of member functions of struct va, you need to use va:: to qualify the names of the members, to distinguish them from anything else with the same name. If this were not the case, then all the good names would be used up by members of classes in the standard library.
It's also good practice to declare variables at the narrowest possible location. Don't clutter the data members of va with things that can be local to it's member functions.
#include <iostream>
#include <string>
using std::cout;
using std::cin;
using std::endl;
struct va {
static constexpr int size = 20;
static constexpr int column = ???;
std::string pro[size][column];
void MainMenu();
void Addition();
void Deletion();
void Search();
void Modify();
void List();
};
int main()
{
setlocale(LC_ALL, "");
va instance;
cout << endl << "Welcome to the League of Legends Pro Players database!" << endl << endl;
cout << endl << "Please, use the menu to access its functions.";
instance.MainMenu();
cout << endl;
return 0;
}
void va::MainMenu()
{
cout << endl << "Main Menu" << endl;
cout << endl << "1: add an entry to the database.";
cout << endl << "2: delete an existing entry from the database.";
cout << endl << "3: search for an existing entry in the database.";
cout << endl << "4: modify an existing entry.";
cout << endl << "5: list all existing entries." << endl;
int i;
cin >> i;
switch(i)
{
case 1: Addition();
case 2: Deletion();
case 3: Search();
case 4: Modify();
case 5: List();
}
}
So heres what im trying to do with my text based rpg now. I want to clean up my main.cpp so that it isnt so long and cluttered, so I am creating a few different cpp files that will hold related items.
I have a maketoon.cpp file that will go through some switch statements that will set all the modifiers(str, int, agl, maxhp) based on the class they choose(class being like lumberjack doctor etc not classes in the object sense of things).
when setting the variables in the maketoon.cpp(within a function called makeMainPlayer() ) i use setters that i made within my createcharacter.h file.
So before you look at my code below, i have a few questions.
1)Where should i create the object(main.cpp, maketoon.cpp). Currently i was creating the object Player in the maketoon.cpp file but im getting these errors:
||=== Build: Debug in 6_days_to_escape (compiler: GNU GCC Compiler) ===|
C:\...\maketoon.cpp||In function 'int makeMainPlayer()':|
C:\...\maketoon.cpp|5|error: 'startChoices' was not declared in this scope|
C:\...\maketoon.cpp|6|error: 'name' was not declared in this scope|
C:\...\main.cpp||In function 'int main()':|
C:\...\main.cpp|39|error: 'Player' was not declared in this scope|
||=== Build failed: 3 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|
2)Should i capitalize the first letting in my object name?
3)how do i call makeMainPlayer in my main.cpp so set that specific objects values to then start the game?
4)Lastly, when i was testing to see if the setters and getters were working, i was getting another Player not declared in this scope error, so i tried just banging out another CreateCharacter Player;at the start of my int main, but i feel that will overwrite all the values set in the later functions, with the default null values.
Also. I know nothing about pointers, but if that is the best way to go(some google searches popped up with this as a fix to similar scenarios)
Seriosly thanks a ton! Im trying to teach myself OOc++ and it is proving difficult. Getting lost in the online tuts and youtube tuts.
//main.cpp
//game rpg
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <conio.h>
#include "createcharacter.h"
#include "maketoon.cpp"
using namespace std;
//is running check
bool running = 1;
//int healedHP(int x, int y);
//int attackedHP(int x, int y);
//user input var+
int userInput = 0;
int startChoices[4] = {0, 0, 0, 0};
string name;
//function declarations
void theStart();
void newGame();
int main (){
void makeMainPlayer();
cout << "Enter your name." << endl;
cin >> name;
cout << "Welcome " << name << "." << endl;
cout << "Strike any key....if you dare......";
getch();
system("cls");
theStart();
makeMainPlayer();
cout << "Name: " << Player.getplayerName() << endl;
cout << "Health: " << Player.getplayerHealth() << endl;
cout << "Strength: " << Player.getStr() << endl;
cout << "Int: " << Player.getInt() << endl;
cout << "Agility: " << Player.getAgl() << endl;
cout << "Difficulty: " << Player.getDifficulty() << endl;
system("pause");
return EXIT_SUCCESS;
}
void theStart()
{
cout << "\n\n";
cout << "\t6 Days to Escape!\n"; //title
cout << "\t\t 1: Play\n"; //main menu options. The first thing the user sees.
cout << "\t\t\t 2: Exit\n";
cin >> userInput;
system("cls");
if(userInput == 1)
{
// Create a new game
newGame();
}
else
{
//bool then false causeing program to exit
running = 0;
}
return;
}
void newGame(){
// there are 4 addresses in this array for the following:
//0. Difficulty
//1. Class
//2. Starting Wep
//3. Boost not implimented yet TODO
//enum class difficulty{simple, easy, hard, impossible};
do{
cout << "Choose Your difficulty: " << endl;
cout << "\t1. Simple - Game practically plays itself." << endl;
cout << "\t2. Easy - Not that easy." << endl;
cout << "\t3. Hard - Zombies do more than crave flesh." << endl;
cout << "\t4. Impossible - You will not make it." << endl;
cin >> startChoices[0];
cout << endl;
system("cls");
if(startChoices[0] < 1 || startChoices[0] > 4){
cout << "Invalid Difficulty Choice. Try again." << endl;}
}while(startChoices[0] < 1 || startChoices[0] > 4);
do{
cout << "Choose your class:" << endl;
cout << "\t1. Lumber Jack - Stong, hard to kill, but slow." << endl;
cout << "\t2. Doctor - Healer, weak but fast. Favors health." << endl;
cout << "\t3. Theif - FAST, Cunning but weak attacks." << endl;
cout << "\t4. Everydayer - Balenced everything." << endl;
cin >> startChoices[1];
cout << endl;
system("cls");
if(startChoices[1] < 1 || startChoices[1] > 4){
cout << "Invalid Class Choice. Try again." << endl;}
}while(startChoices[1] < 1 || startChoices[1] > 4);
do{
cout << "Choose your starting Weapon:" << endl;
cout << "\t1. Axe" << endl;
cout << "\t2. Crowbar" << endl;
cout << "\t3. Swiss army knife" << endl;
cout << "\t4. Ice pick" << endl;
cin >> startChoices[2];
cout << endl;
if(startChoices[0] < 1 || startChoices[0] > 4){
cout << "Invalid Weapon Choice. Try again." << endl;}
}while(startChoices[2] < 1 || startChoices[2] > 4);
}
//----------------------------------------------------------------------------------------
//createcharacter.h
#ifndef CREATECHARACTER_H
#define CREATECHARACTER_H
class CreateCharacter{
public:
//setter
void setplayerName(std::string x){
playerName = x;}
void setwepSpeed(int v){
wepSpeed = v;}
void setplayerHealth(int h){
playerHealth = h;}
void setplayerMaxHealth(int mh){
playerMaxHealth = mh;}
void setplayerStr(int s){
playerStr = s;}
void setplayerAgl(int a){
playerAgl = a;}
void setplayerInt(int i){
playerInt = i;}
void setplayerDifficulty(int d){
playerDifficulty = d;}
void setwepbaseDmg(int j){
wepbaseDmg = j;}
//getters
std::string getplayerName(){
return playerName;}
int getplayerHealth(){
return playerHealth;}
int getMaxHealth(){
return playerMaxHealth;}
int getStr(){
return playerStr;}
int getAgl(){
return playerAgl;}
int getInt(){
return playerInt;}
int getDifficulty(){
return playerDifficulty;}
private:
std::string playerName;
int playerHealth;
int playerMaxHealth; //absolute max = 200
int playerStr; // absolute max = 20
int playerAgl;// absolute max = 20
int playerInt;// absolute max = 20
int playerDifficulty; // absolute max = 4
//items
int wepbaseDmg;
int wepSpeed;
};
#endif
//------------------------------------------------------------------------------
//maketoon.cpp
//This was my attempt based off google....
//int* startChoices[4]={getDifficulty(), get};
int makeMainPlayer(){
CreateCharacter Player;
Player.setplayerDifficulty(startChoices[0]);
Player.setplayerName(name);
switch(startChoices[1]){
case 1:
Player.setplayerMaxHealth(175);
Player.setplayerStr(18);
Player.setplayerAgl(10);
Player.setplayerInt(6);
break;
case 2:
Player.setplayerMaxHealth(200);
Player.setplayerStr(9);
Player.setplayerAgl(13);
Player.setplayerInt(15);
break;
case 3:
Player.setplayerMaxHealth(100);
Player.setplayerStr(11);
Player.setplayerAgl(20);
Player.setplayerInt(10);
break;
case 4:
Player.setplayerMaxHealth(150);
Player.setplayerStr(12);
Player.setplayerAgl(12);
Player.setplayerInt(13);
break;
}
switch(startChoices[2]){
case 1:
Player.setwepbaseDmg(40);
Player.setwepSpeed(4);
break;
case 2:
Player.setwepbaseDmg(30);
Player.setwepSpeed(5);
break;
case 3:
Player.setwepbaseDmg(25);
Player.setwepSpeed(8);
break;
case 4:
Player.setwepbaseDmg(20);
Player.setwepSpeed(10);
break;
}
return 0;
}
I have a class called figGeom. The class circulo inherits from figGeom.
I need to create a class that allows me to save object pointers of type figGeom in an array. Can you help me?
I am also interested to know how to add pointers or memory addresses to the array.
Note: I have also rectangle and triangle classes, but I removed those to make the post shorter and more readable.
My current code gives me an error.
figuraGeom.h
#define TRIANGULO 0
#define RECTANGULO 1
#define CIRCULO 2
class figGeom
{
double area;
int tipoFig;
public:
figGeom();
figGeom(int);
void setArea(double);
double getArea();
void setTipoFig(int);
int getTipoFig();
virtual double calcArea()=0;
virtual void toString()=0;
};
class circulo:public figGeom
{
//atributos
double radio;
public:
circulo();
circulo(double);
void setRadio(double);
double getRadio();
double calcArea();
void toString();
};
figuraGeom.cpp
#include "figuraGeom.h"
#define _USE_MATH_DEFINES
#include <Math.h>
#include <string>
#include <iostream>
using namespace std;
//FIGGEOM
//Dispositivo
figGeom::figGeom(){}
figGeom::figGeom(int itipoDis){
setTipoFig(itipoDis);
}
void figGeom::setArea(double iArea){area = iArea;}
double figGeom::getArea(){return area;}
void figGeom::setTipoFig(int iTipoDis){tipoFig = iTipoDis;}
int figGeom::getTipoFig(){return tipoFig;}
//CIRCULO
circulo::circulo(){}
circulo::circulo(double iRadio):figGeom(CIRCULO){setRadio(iRadio);}
void circulo::setRadio(double iRadio){radio = iRadio;}
double circulo::getRadio(){return radio;}
double circulo::calcArea(){return M_PI*pow(getRadio(),2);}
void circulo::toString(){cout << endl << endl << " Tipo Figura: Circulo" << endl << endl;}
//LISTA FIGURAS
listaFiguras::listaFiguras(){
*lista = NULL;
setNumElementos(0);
}
listaFiguras::~listaFiguras(){
vaciarLista();
}
void listaFiguras::setNumElementos(int iNum){numElementos = iNum;}
int listaFiguras::getNumElementos(){return numElementos;}
void listaFiguras::vaciarLista()
{
free(lista);
}
main.cpp
#include "figuraGeom.h"
#include <iostream>
using namespace std;
int tipoFig;
char opcion;
figGeom * dI = NULL;
listaFiguras* listaFig = new listaFiguras();
void menu();
void menu_add_figura();
figGeom* pedirTriangulo();
figGeom* pedirRectangulo();
figGeom* pedirCirculo();
void menu();
void main()
{
setlocale(LC_ALL, ""); //Configuración Regional
menu();
}
void menu()
{
do{
cout << "SELECCIONA UNA OPCIÓN" << endl;
cout << " [1]Añadir elemento" << endl;
cout << " [2]Ver elemento" << endl;
cout << " [3]Eliminar elemento" << endl;
cout << " [4]Ver todos los elementos" << endl;
cout << " [5]Eliminar todos los elementos" << endl << endl;
cout << " [6]Salir" << endl << endl;
cout << "Opción: ";
cin >> opcion;
switch (opcion){
case '1':
menu_add_figura();
break;
case '2':
break;
case '3':
break;
}
}while(opcion != '6');
}
void menu_add_figura()
{
do{
system("cls"); //limpiamos pantalla
cout << "¿Qué tipo de figura desea crear?" << endl;
cout << " [1]Triangulo" << endl;
cout << " [2]Rectangulo" << endl;
cout << " [3]Circulo" << endl;
cout << " [4]Salir" << endl << endl;
cout << "Figura: ";
cin >> opcion;
//PUNTERO AUX
//listaFiguras-
int new_numElem = (listaFig->getNumElementos()) + 1;
listaFig->setNumElementos(new_numElem);
figGeom** vector = new figGeom*[new_numElem];
switch (opcion){
case '1':
dI = pedirTriangulo(); //dI
*vector[new_numElem-1] = *dI;
break;
case '2':
dI = pedirRectangulo(); //dI
*vector[new_numElem-1] = *dI;
break;
case '3':
dI = pedirCirculo(); //dI
*vector[new_numElem-1] = *dI;
break;
}
if(opcion != '4')
{
//cout << endl << " Area: " << dI->calcArea() << endl << endl; //Mostrar area
cout << endl << " Area: " << vector[new_numElem-1]->calcArea << endl << endl; //Mostrar area
system("pause"); //pausa
system("cls"); //limpiamos pantalla
}else delete dI;
}while(opcion != '4');
}
figGeom* pedirCirculo()
{
int radio;
cout << " -Radio: ";
cin >> radio;
figGeom* dIaux;
dIaux = new circulo(radio);
return dIaux;
}
Don't use raw pointers. Using raw pointers often leads to memory leaks. Instead, use C++11's (or Boost's) various smart pointer classes such as std::unique_ptr or std::shared_ptr. They will handle the issue of deleting objects when they're no longer needed.
#include <memory>
std::shared_ptr<figGeom> createFigure()
{
std::shared_ptr<figGeom> thing(new figGeom(/* whatever */));
return thing;
}
You don't need to use a simple array, and you certainly don't need to write your own container class. Instead, use one of the many containers from the standard library... they're fast, efficient, handle their own memory allocation and deallocation and perhaps most importantly, they've been well tested. std::vector or std::array woudl work just fine... use vectors when you only know the size of the container at runtime, and arrays when you know the size of the container at compile time. Both containers can be accessed in the same way as a standard simple array.
#include <vector>
std::vector<std::unique_ptr<figGeom>> createFigures()
{
std::vector<std::unique_ptr<figGeom>> figures;
figures.push_back(createFigure());
figures[0].setArea(1234.56);
return figures;
}
With such a simple, lightweight class as this, you don't really need to use new at all... you can allocate instances on the stack, and just copy them into a container when needed.
figGeom createShape()
{
figGeom shape(/* whatever */);
return shape;
}
std::vector<figGeom> createShapes()
{
std::vector<figGeom> shapes;
shapes.push_back(createShape());
return shapes;
}
You can do this:
figGeom* array[10];// change 10 to any number you need
then create pointer to circulo class and save it in the array
for(int i=0;i<10;i++){
array[i] = new circulo(/*parameters to constructor*/);
}
after you done with the objects, you should free the memory
for(int i=0;i<10;i++){
delete array[i];// Note, your destructor in figGeom class should be virtual
}
Here's the code that triggers the error (Player.cpp):
#include "Library.h"
Player::Player(){
//generate player stats
str = rand()%6+1+1;
inte = rand()%6+1;
c = (rand()%6+1)+floor(str/3);
wis = rand()%6+1+floor(inte/4);
ref = rand()%6+1+floor(wis/4);
i = floor(ref/3);
hp = floor((str+(wis/3)+(ref/2)));
xp = 0;
}
//printStats (constant Player player reference)
//prints player's stats
void Player::printStats() const{
cout << "\nSTR: " << str << endl;
cout << "INTE: " << inte << endl;
cout << "C: " << c << endl;
cout << "WIS: " << wis << endl;
cout << "REF: " << ref << endl;
cout << "I: " << i << endl;
cout << "HP: " << hp << endl;
cout << "XP: " << xp << endl;
cout << "Gold: " << gold << endl;
cout << "Level: " << lvl << endl << endl;
}
int Player::giveOptions(int amount,string op1, string op2, string op3, string op4, string op5){
cout << "Type the number then press the enter key to choose or type 'help' for extra commands." << endl;
for(int i=1;i<=amount;i++){
string s;
switch(i){
case 1:
s = op1;
break;
case 2:
s = op2;
break;
case 3:
s = op3;
break;
case 4:
s = op4;
break;
case 5:
s = op5;
break;
}
cout << i << ". " << s << endl;
}
while(true){
string s;
cin >> s;
if (s == "1")
return 1;
else if (s == "2")
return 2;
else if (s == "3")
return 3;
else if (s == "4")
return 4;
else if (s == "5")
return 5;
else{
if (s == "stats")
printStats();
else if (s == "help"){
cout << "Type the number that is next to the option you wish to choose then press the enter key, or 'stats' to print all of your stats." << endl;
cout << "E.G:\n1. Town\nI want to go to the town\n1" << endl;
}
else
cout << "Command not recognised. If you're confused, type 'help'." << endl;
}
}
}
(Original question below)
I'm fairly basic in C++, and I'm not sure why this is producing an error. In Player.cpp, all members of Entity that I thought were inherited produce the error, "x is not a member of Player". My only thought is that I'm using inheritance wrong.
Entity.h:
#include "Library.h"
using namespace std;
class Entity {
public:
void printStats() const;
protected:
//player stats
std::string name;
double str; //strength
double wis; //wisdom
double ref; //reflex
double hp; //health points
double i; //initiative
double inte; //intelligence
double c; //courage
int gold; //gold
int xp; //experience
int ap; //armour points
int wd; //weapon damage
int lvl; //level
int sp; //skill points
};
Player.h
#include "Library.h"
using namespace std;
class Player: public Entity{
public:
Player();
int giveOptions(int amount, string op1, string op2, string op3, string op4, string op5);
};
void Player::printStats() const
Should be, according to your headers:
void Entity::printStats() const
On the includes, do one of these, whichever suits your code best:
1.
Player.h must include Entity.h
Library.h should not include Player.h or Entity.h
Player.h and/or Entity.h can include Library.h if really needed.
or 2.
Player.h must include Entity.h, but not Library.h
Entity.h must not include Library.h
Library.h can include Player.h and/or Entity.h
This avoids the cyclic dependencies you currently have - which leads to Player being defined before Entity and giving the base class undefined error.
As the compiler compliains - neither the class Entity nor the Player has a member variable called x. You need to include "Entity.h" in the Player header file, since in the current translation unit compiler doesn't know what Player is.