c++oopheader-filespreprocessor-directiveclass-hierarchy

I can't divide my working code into class-specific header/cpp files without getting an C2504 error : base class undefined


Using Visual Studio 2022, I'm making a simple text RPG in plain C++. I've been playing around with Object Oriented Paradigm and the code is working as intended when in a single file, but upon dividing it into 5 separate classes, I can't get it to compile successfully without generating a "base class not defined" error. After that, all base class methods fail to work in derived classes as well.

Can anyone shed any light on the situation? I tried finding answers on a similar problem, but I fail to understand the concept.

I have a base class called Player, 3 derived classed, and a main.cpp file that has some utility functions.

Enemy.h:

#pragma once
#include "Player.h"


class Enemy : public Player
{

private:
    int armor;
public:
    void setArmor(int x);
    int getArmor();
    Enemy(int dmg, int mhp, int arm);
    void show();

};

Player.h file:

#pragma once
#include <iostream>
#include "Warrior.h"
#include "Wizard.h"
#include "Enemy.h"
class Enemy;

using namespace std;

class Player
{
private:
    int health, MaxHealth, level, damage, block;
public: 
    void setHealth(int x);
    int getHealth();
    void setMaxHealth(int x);
    int getMaxHealth();
    void setLevel(int x);
    int getLevel();
    void setDamage(int x);
    int getDamage();
    void setBlock(int x);
    int getBlock();
    Player();
    virtual ~Player();
    virtual void show();
    void heal();
    void attack(Enemy& y);

};

Warrior.h file:

#pragma once
#include "Player.h"
class Player;

class Warrior : public Player
{
private: 
    int armor;
public:  
    void setArmor(int x);
    int getArmor();
    Warrior();
    virtual ~Warrior();
    void show();
    void showCombat(Enemy& y);
    void spellbook(Enemy& y);
};

Warrior.cpp:

#include "Warrior.h"

void Warrior::showCombat(Enemy& y)
{
    int menu;
    show();
    cout << "\n\n";
    y.show();
    cout << "Select an action: \n" << "1. Basic attack(deals " << getDamage() << " damage)\n";
    cout << "2. Block(blocks " << getLevel() + 5 << " damage)\n";
    cout << "3. Cast a spell\n";
    cin >> menu;
    switch (menu)
    {
    case 1:
    {
        attack(y);
        break;
    }
    case 2:
    {
        setBlock(getLevel() + 5);
        break;
    }
    case 3:
    {
        spellbook(y);
        break;
    }
    }
    int razlika = y.getDamage() - getArmor() - getBlock();
    if (razlika < 0) {razlika = 0};
    cout << "The enemy attacks! He deals " << razlika << " damage!\n";
    setHealth(getHealth() - razlika);
    setBlock(0);
}
void Warrior::spellbook(Enemy& y)
{
    cout << "You are a warrior, you can't cast any spells!\n";
    showCombat(y);
}
void Warrior::setArmor(int x)
{
    armor = x;
}
int Warrior::getArmor()
{
    return armor;
}
Warrior::Warrior()
{
    setMaxHealth(getMaxHealth() * 1.1);
    armor = 1;
    setHealth(getMaxHealth());
}
Warrior::~Warrior()
{
};
void Warrior::show()
{
    cout << "Character stats:\n";
    cout << "Level: " << getLevel() << "\n";
    cout << "HP: " << getHealth() << "/" << getMaxHealth() << "\n";
    cout << "Damage: " << getDamage() << "\n";
    cout << "Armor: " << armor << "\n";
}

Player.cpp:

#include "Player.h"


void Player::attack(Enemy& y)
{
    int difference = getDamage() - y.getArmor();
    if (difference < 0)
        difference = 0;
    cout << "You attack the enemy! You deal " << difference << "damage!\n";
    y.setHealth(y.getHealth() - difference);
};
void Player::heal()
{
    setHealth(getMaxHealth());
}

void Player::setHealth(int x)
{
    health = x;
}
int Player::getHealth()
{
    return health;
}
void Player::setMaxHealth(int x)
{
    MaxHealth = x;
}
int Player::getMaxHealth()
{
    return MaxHealth;
}
void Player::setLevel(int x)
{
    level = x;
}
int Player::getLevel()
{
    return level;
}
void Player::setDamage(int x)
{
    damage = x;
}
int Player::getDamage()
{
    return damage;
};
void Player::setBlock(int x)
{
    block = x;
}
int Player::getBlock()
{
    return block;
}
Player::Player()
{
    health = 30;
    MaxHealth = 30;
    level = 1;
    damage = 5;
    block = 0;
}

Player::~Player()
{
};
void Player::show()
{
    cout << "Character stats:\n";
    cout << "Level: " << getLevel() << "\n";
    cout << "HP: " << getHealth() << "/" << getMaxHealth() << "\n";
    cout << "Damage: " << getDamage() << "\n";
}

main.cpp:

#include <iostream>
#include "Player.h"

using namespace std;

void WarriorGameplay();
void ClassChoice();
int nasumicni();
void playAgain();
void WizardGameplay();


int main()
{
    ClassChoice();
    return 0;
}

void ClassChoice()
{
    int choice;
    cout << "Select the class you want to play (1/2):\n";
    cout << "1. Warrior\n" << "2.Wizard\n";
    cin >> choice;
    if (choice == 1)
    {
        WarriorGameplay();
    }
    else if (choice == 2)
    {
        WizardGameplay();
    }
    else
    {
        cout << "Invalid input, please enter 1 for warrior, 2 for wizard.\n";
        ClassChoice();
    }
}

void WarriorGameplay()
{
    Warrior player;
    int choice, lvlup;
    cout <<
        "You have chosen to play as the mighty warrior! Your health points have been increased by 10% and you have armor available at your disposal!\n";
    cout <<
        "Armor will decrease incoming physical damage by 1 for each point of armor your character has.\n";
    cout <<
        "/***************************************************************/\n";
    player.show();
    do
    {
        cout <<
            "You lie awake in a cave. There are three corridors in front of you, none different then the other. Which corridor do you choose?(1/2/3)\n";
        cout << "1. Corridor on the left.\n" << "2. Corridor in the middle.\n"
            << "3. Corridor on the right.\n";
        cin >> choice;
        switch (choice)
        {
        case 1:
        {
            cout << "You opt to follow the corridor on the left. The scent of dead animals start to suround you. Suddenly, a goblin jumps out of a hole in the wall!\n";
            Enemy goblin(player.getLevel() * 4, player.getLevel() * 15, player.getLevel() * 0);
            do
            {
                player.showCombat(goblin);
            } while (player.getHealth() > 0 && goblin.getHealth() > 0);
            if (player.getHealth() <= 0)
            {
                cout << "You died!\n";
                playAgain();

            }
            else if (goblin.getHealth() <= 0)
                cout << "Congratulations! You killed the goblin!\n";
            player.setLevel(player.getLevel() + 1);
            cout << "You gained a level and are now level " << player.getLevel() << "!\n";
            cout << "Select a bonus:\n" << "1. +1 damage\n" << "2. +1 armor\n";
            cin >> lvlup;
            switch (lvlup)
            {
            case 1:
            {
                player.setDamage(player.getDamage() + 1);
                cout << "You gained 1 damage and now have " << player.getDamage() << " damage!\n";
                break;
            }
            case 2:
            {
                player.setArmor(player.getArmor() + 1);
                cout << "You gained 1 armor and now have " << player.getArmor() << " armor!\n";
                break;
            }
            }
            player.heal();
            cout << "\n\n\nAfter walking for some time down the corridor, you see a cloaked figure standing in your way. \
                he raises his hand towards you: \"Approach, child, and learn the secret of eternal life.\"\n";
            cout << "What do you want to do?\n";
            cout << "1. Approach the cloaked figure (50% chance for +5 max health)\n";
            cout << "2. Tell the figure you think immortality is an absurd social construct and you prefer a limited lifespan.\
                (33% chance of getting attacked)\n";
            cin >> choice;
            int roll = nasumicni();
            if (choice == 1)
            {
                cout << "You decide to approach the figure.\n";
                if (roll % 2 == 0)
                {
                    cout << "The cloaked figure hands you a trinket best described as a dried prune, but a bit more bloodier. He urges\
                    you to eat it, and you do.\n";
                    cout << "You recieve +5 max health points!\n";
                    player.setMaxHealth(player.getMaxHealth() + 5);
                }
                else
                {
                    cout << "While approaching the cloaked figure, you notice him slowly vanishing in the mist. Upon arriving to the \
                    place where he stood, you find no trace of him left. You can't help but feel tricked.\
                    You continue your journey.\n";
                }

            }
            else if (choice == 2)
            {
                cout << "You decide to tell the figure what you think of its' weak life philosophy.\n";
                if (roll == 1 || roll == 2)
                {
                    cout << "The figure is offended by your gibberish and decides to attack!You rush to defend yourself.\n";
                    Enemy cloakedFigure(player.getLevel() * 4 - 2, player.getLevel() * 15, player.getLevel() * 0 + 1);
                    do
                    {
                        player.showCombat(cloakedFigure);
                    } while (player.getHealth() > 0 && cloakedFigure.getHealth() > 0);
                    if (player.getHealth() <= 0)
                    {
                        cout << "You died!\n";
                        playAgain();
                    }
                    else if (cloakedFigure.getHealth() <= 0)
                        cout << "After a long and weary combat, you manage to outwitt the figure and put him to dust. Behind him \
                        remains a shiny orb that you feel oddly compelled to. You pick it up and put it into your pocket.(+2 damage)\n";
                    player.setDamage(player.getDamage() + 2);
                    cout << "Congratulations, you leveled up! Choose your reward: \n";
                    cout << "1. +5 max HP\n" << "2. +2 Armor \n";
                    cin >> lvlup;
                    player.heal();
                    switch (lvlup)
                    {
                    case 1:
                    {
                        player.setMaxHealth(player.getMaxHealth() + 5);
                        cout << "You gained 5 max HP and now have " << player.getMaxHealth() << " max HP!\n";
                        player.heal();
                        break;
                    }
                    case 2:
                    {
                        player.setArmor(player.getArmor() + 2);
                        cout << "You gained 2 armor and now have " << player.getArmor() << " armor!\n";
                        break;
                    }
                    }
                    player.show();
                }
                else
                {
                    cout << "Mortal fool, you know not of the things lurking behind the dreams of men and shadows.\n";
                    cout << "With a cryptic message, the figure dissappears. A little confused (but otherwise healthy), you \
                    continue your journey.\n";
                }
            }
            break;
        }
        case 2:
        {
            cout << "Corridor in the middle.\n";
            break;
        }
        case 3:
        {
            cout << "Corridor on the right.\n";
            break;
        }
        default:
        {
            cout << "Wrong choice! Please enter a number 1-3.\n";
            break;
        }

        }
        cout << "You reach the end of the corridor. In the middle of the room, a horned demon is sitting and gazing you with his \
        flaming red eyes.\n\"I've been waiting for you,\" he says. Without breaking eye contact, he pulls a two-faced axe from his \
           back. You prepare for combat.\n";
        Enemy finalBoss(player.getLevel() * 4, player.getLevel() * 15, player.getLevel() * 0 + 1);
        do
        {
            player.showCombat(finalBoss);
        } while (player.getHealth() > 0 && finalBoss.getHealth() > 0);
        if (player.getHealth() <= 0)
        {
            cout << "You died!\n";
            playAgain();
        }
        else if (finalBoss.getHealth() <= 0)
        {
            cout << "After what seemed like a lifetime of drawn out combat, your last slice brings the demon to its' knees.\
            \"This is not over,\"he snarls, \"The world of mortals shall meet its doom!\" With continued muttering in Latin, \
            the demon slowly crumbles down and dies.\n";
            cout << "Congratulations! You win!\n";
            playAgain();
        }


    } while (choice != 1 && choice != 2 && choice != 3);

}

int nasumicni()
{
    srand(time(0));
    int a = rand() % 6 + 1;
    return a;
}
void playAgain()
{
    cout << "Play again?(y/n)";
    char pick;
    cin >> pick;
    if (pick == 'y')
        ClassChoice();
    else if (pick == 'n')
        exit(0);
}
void WizardGameplay()
{
    Wizard player;
    int choice, lvlup;
    cout <<
        "You have chosen to play as the mysterious wizard! You gain mighty mana at your disposal, but start with decreased\
         damage attribute!\n";
    cout <<
        "Mana is used for casting spells.\n";
    cout <<
        "\n";
    player.show();
    do
    {
        cout <<
            "You lie awake in a cave. There are three corridors in front of you, none different then the other. Which corridor do you choose?(1/2/3)\n";
        cout << "1. Corridor on the left.\n" << "2. Corridor in the middle.\n"
            << "3. Corridor on the right.\n";
        cin >> choice;
        switch (choice)
        {
        case 1:
        {
            cout << "You opt to follow the corridor on the left. The scent of dead animals start to suround you. Suddenly, a goblin jumps out of a hole in the wall!\n";
            Enemy goblin(player.getLevel() * 4, player.getLevel() * 15, player.getLevel() * 0);
            do
            {
                player.showCombat(goblin);
            } while (player.getHealth() > 0 && goblin.getHealth() > 0);
            if (player.getHealth() <= 0)
            {
                cout << "You died!\n";
                playAgain();

            }
            else if (goblin.getHealth() <= 0)
                cout << "Congratulations! You killed the goblin!\n";
            player.setLevel(player.getLevel() + 1);
            cout << "You gained a level and are now level " << player.getLevel() << "!\n";
            cout << "Select a bonus:\n" << "1. +2 damage\n" << "2. +5 mana\n";
            cin >> lvlup;
            switch (lvlup)
            {
            case 1:
            {
                player.setDamage(player.getDamage() + 2);
                cout << "You gained 2 damage and now have " << player.getDamage() << " damage!\n";
                break;
            }
            case 2:
            {
                player.setMaxMana(player.getMaxMana() + 5);
                cout << "You gained 5 max mana and now have " << player.getMaxMana() << " max mana!\n";
                break;
            }
            }
            player.heal();
            player.replenishMana();
            cout << "\n\n\nAfter walking for some time down the corridor, you see a cloaked figure standing in your way. \
                he raises his hand towards you: \"Approach, child, and learn the secret of eternal life.\"\n";
            cout << "What do you want to do?\n";
            cout << "1. Approach the cloaked figure (50% chance for +5 max health)\n";
            cout << "2. Tell the figure you think immortality is an absurd social construct and you prefer a limited lifespan.\
                (33% chance of getting attacked)\n";
            cin >> choice;
            int roll = nasumicni();
            if (choice == 1)
            {
                cout << "You decide to approach the figure.\n";
                if (roll % 2 == 0)
                {
                    cout << "The cloaked figure hands you a trinket best described as a dried prune, but a bit more bloodier. He urges\
                    you to eat it, and you do.\n";
                    cout << "You recieve +5 max health points!\n";
                    player.setMaxHealth(player.getMaxHealth() + 5);
                    player.heal();
                }
                else
                {
                    cout << "While approaching the cloaked figure, you notice him slowly vanishing in the mist. Upon arriving to the \
                    place where he stood, you find no trace of him left. You can't help but feel tricked.\
                    You continue your journey.\n";
                }

            }
            else if (choice == 2)
            {
                cout << "You decide to tell the figure what you think of its' weak life philosophy.\n";
                if (roll == 1 || roll == 2)
                {
                    cout << "The figure is offended by your gibberish and decides to attack!You rush to defend yourself.\n";
                    Enemy cloakedFigure(player.getLevel() * 4 - 2, player.getLevel() * 15, player.getLevel() * 0 + 1);
                    do
                    {
                        player.showCombat(cloakedFigure);
                    } while (player.getHealth() > 0 && cloakedFigure.getHealth() > 0);
                    if (player.getHealth() <= 0)
                    {
                        cout << "You died!\n";
                        playAgain();
                    }
                    else if (cloakedFigure.getHealth() <= 0)
                        cout << "After a long and weary combat, you manage to outwitt the figure and put him to dust. Behind him \
                        remains a shiny orb that you feel oddly compelled to. You pick it up and put it into your pocket.(+2 damage)\n";
                    player.setDamage(player.getDamage() + 2);
                    cout << "Congratulations, you leveled up! Choose your reward: \n";
                    cout << "1. +5 max HP\n" << "2. +2 Damage \n";
                    cin >> lvlup;
                    player.heal();
                    switch (lvlup)
                    {
                    case 1:
                    {
                        player.setMaxHealth(player.getMaxHealth() + 5);
                        cout << "You gained 5 max HP and now have " << player.getMaxHealth() << " max HP!\n";
                        break;
                    }
                    case 2:
                    {
                        player.setDamage(player.getDamage() + 2);
                        cout << "You gained 2 damage and now have " << player.getDamage() << " damage!\n";
                        break;
                    }
                    }
                    player.show();
                }
                else
                {
                    cout << "Mortal fool, you know not of the things lurking behind the dreams of men and shadows.\n";
                    cout << "With a cryptic message, the figure dissappears. A little confused (but otherwise healthy), you \
                    continue your journey.\n";
                }
            }
            break;
        }
        case 2:
        {
            cout << "Corridor in the middle.\n";
            break;
        }
        case 3:
        {
            cout << "Corridor on the right.\n";
            break;
        }
        default:
        {
            cout << "Wrong choice! Please enter a number 1-3.\n";
            break;
        }

        }
        cout << "You reach the end of the corridor. In the middle of the room, a horned demon is sitting and gazing you with his \
        flaming red eyes.\n\"I've been waiting for you,\" he says. Without breaking eye contact, he pulls a two-faced axe from his \
           back. You prepare for combat.\n";
        Enemy finalBoss(player.getLevel() * 4, player.getLevel() * 15, player.getLevel() * 0 + 1);
        do
        {
            player.showCombat(finalBoss);
        } while (player.getHealth() > 0 && finalBoss.getHealth() > 0);
        if (player.getHealth() <= 0)
        {
            cout << "You died!\n";
            playAgain();
        }
        else if (finalBoss.getHealth() <= 0)
        {
            cout << "After what seemed like a lifetime of drawn out combat, your last slice brings the demon to its' knees.\
            \"This is not over,\"he snarls, \"The world of mortals shall meet its doom!\" With continued muttering in Latin, \
            the demon slowly crumbles down and dies.\n";
            cout << "Congratulations! You win!\n";
            playAgain();


        }


    } while (choice != 1 && choice != 2 && choice != 3);

}

Error message:

1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\Warrior.h(6,1): error C2504: 'Player': base class undefined
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\Warrior.h(15,21): error C2061: syntax error: identifier 'Enemy'
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\Warrior.h(16,20): error C2061: syntax error: identifier 'Enemy'
1>Top in: C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\Wizard.h
1>Before class in: C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\Wizard.h
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\Wizard.h(7,1): error C2504: 'Player': base class undefined
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\Wizard.h(19,20): error C2061: syntax error: identifier 'Enemy'
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\Wizard.h(21,21): error C2061: syntax error: identifier 'Enemy'
1>headeri_praksa.cpp
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\Warrior.h(6,1): error C2504: 'Player': base class undefined
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\Warrior.h(15,21): error C2061: syntax error: identifier 'Enemy'
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\Warrior.h(16,20): error C2061: syntax error: identifier 'Enemy'
1>Top in: C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\Wizard.h
1>Before class in: C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\Wizard.h
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\Wizard.h(7,1): error C2504: 'Player': base class undefined
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\Wizard.h(19,20): error C2061: syntax error: identifier 'Enemy'
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\Wizard.h(21,21): error C2061: syntax error: identifier 'Enemy'
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\Enemy.h(6,1): error C2504: 'Player': base class undefined
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\headeri_praksa.cpp(63,33): error C2039: 'getLevel': is not a member of 'Warrior'
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\Warrior.h(5): message : see declaration of 'Warrior'
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\headeri_praksa.cpp(63,56): error C2039: 'getLevel': is not a member of 'Warrior'
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\Warrior.h(5): message : see declaration of 'Warrior'
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\headeri_praksa.cpp(63,80): error C2039: 'getLevel': is not a member of 'Warrior'
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\Warrior.h(5): message : see declaration of 'Warrior'
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\headeri_praksa.cpp(63,25): error C2512: 'Enemy::Enemy': no appropriate default constructor available
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\headeri_praksa.cpp(66,41): error C2660: 'Warrior::showCombat': function does not take 1 arguments
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\Warrior.h(15,10): message : see declaration of 'Warrior::showCombat'
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\headeri_praksa.cpp(67,29): error C2039: 'getHealth': is not a member of 'Warrior'
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\Warrior.h(5): message : see declaration of 'Warrior'
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\headeri_praksa.cpp(67,55): error C2039: 'getHealth': is not a member of 'Enemy'
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\Player.h(6): message : see declaration of 'Enemy'
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\headeri_praksa.cpp(68,24): error C2039: 'getHealth': is not a member of 'Warrior'
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\Warrior.h(5): message : see declaration of 'Warrior'
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\headeri_praksa.cpp(74,29): error C2039: 'getHealth': is not a member of 'Enemy'
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\Player.h(6): message : see declaration of 'Enemy'
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\headeri_praksa.cpp(76,20): error C2039: 'setLevel': is not a member of 'Warrior'
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\Warrior.h(5): message : see declaration of 'Warrior'
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\headeri_praksa.cpp(76,36): error C2039: 'getLevel': is not a member of 'Warrior'
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\Warrior.h(5): message : see declaration of 'Warrior'
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\headeri_praksa.cpp(77,71): error C2039: 'getLevel': is not a member of 'Warrior'
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\Warrior.h(5): message : see declaration of 'Warrior'
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\headeri_praksa.cpp(84,24): error C2039: 'setDamage': is not a member of 'Warrior'
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\Warrior.h(5): message : see declaration of 'Warrior'
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\headeri_praksa.cpp(84,41): error C2039: 'getDamage': is not a member of 'Warrior'
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\Warrior.h(5): message : see declaration of 'Warrior'
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\headeri_praksa.cpp(85,71): error C2039: 'getDamage': is not a member of 'Warrior'
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\Warrior.h(5): message : see declaration of 'Warrior'
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\headeri_praksa.cpp(95,20): error C2039: 'heal': is not a member of 'Warrior'
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\Warrior.h(5): message : see declaration of 'Warrior'
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\headeri_praksa.cpp(112,28): error C2039: 'setMaxHealth': is not a member of 'Warrior'
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\Warrior.h(5): message : see declaration of 'Warrior'
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\headeri_praksa.cpp(112,48): error C2039: 'getMaxHealth': is not a member of 'Warrior'
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\Warrior.h(5): message : see declaration of 'Warrior'
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\headeri_praksa.cpp(128,48): error C2039: 'getLevel': is not a member of 'Warrior'
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\Warrior.h(5): message : see declaration of 'Warrior'
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\headeri_praksa.cpp(128,75): error C2039: 'getLevel': is not a member of 'Warrior'
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\Warrior.h(5): message : see declaration of 'Warrior'
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\headeri_praksa.cpp(128,99): error C2039: 'getLevel': is not a member of 'Warrior'
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\Warrior.h(5): message : see declaration of 'Warrior'
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\headeri_praksa.cpp(128,40): error C2512: 'Enemy::Enemy': no appropriate default constructor available
1>C:\Users\mihai\source\repos\headeri_praksa\headeri_praksa\headeri_praksa.cpp(131,56): error C2660: 'Warrior::showCombat': function does not take 1 arguments

Solution

  • Okay, you're doing a few things you probably shouldn't do.

    First, you have Player.h include a bunch of things.

    #include <iostream>
    #include "Warrior.h"
    #include "Wizard.h"
    #include "Enemy.h"
    class Enemy;
    
    using namespace std;
    

    You've already gotten comments not to do the using namespace std thing. That's an anti-pattern, anyway, but it's really a bad idea in an include file. You can find all sorts of references why you shouldn't do that.

    But you're also including a bunch of .h files that you then don't reference. Remove them. Basically that means all of them.

    So here's what is happening (I think).

    Player.h tries to pull in Warrior.h.

    Warrior.h tries to pull in Player.h, but because of the #pragma once it won't get anywhere. Later, it references Player, which hasn't been defined yet.

    And you can't subclass from a class if you don't have the full definition.

    So, to fix this, Player.h should NOT #include anything else. You can do a forward definition of class Enemy like you do so the final method in Player works.

    That should fix quite a bit.