I'm trying to learn C++ and currently I'm trying to know how to implement an object composition in this language.
I have a Character
class which is inherited by a Hero
and a Monster
class.
A Character
has a NormalAbility
and a SpecialAbility
.
I've made the NormalAbility
and SpecialAbility
classes and both are inheriting an Ability
superclass.
My problem is that when I put the #include "Character.h" in Ability.h the normalAbility and specialAbility variables in Character.h
don't get recognized as their respected classes. Errors such as "syntax error : identifier string" shows in the headers of both Ability inherited classes
Here's my code:
Character.h
#pragma once
#include <string>
#include "NormalAbility.h"
#include "SpecialAbility.h"
using namespace std;
class Character
{
public:
Character(string name, string type, int hp, NormalAbility na,
SpecialAbility sa);
bool isDead();
void damage(int amt);
void heal(int amt);
void attack(Character* c, int amt);
private:
string name;
string type;
int hp;
int maxHp;
NormalAbility* normalAblity;
SpecialAbility* specialAbility;
}
Character.cpp
#include "Character.h"
#include <iostream>
Character::Character(string name, string type, int hp, NormalAbility* na,
SpecialAbility* sa)
{
this->name = name;
this->type = type;
this->maxHp = hp;
this->hp = hp;
normalAbility = na;
specialAbility = sa;
}
bool Character::isDead(){
return hp <= 0;
}
void Character::damage(int amt){
if (hp > 0){
hp -= amt;
}
else{
hp = 0;
}
}
void Character::heal(int amt){
if (hp + amt > maxHp){
hp = maxHp;
}
else{
hp += amt;
}
}
void Character::attack(Character* c, int amt){
c->damage(amt);
}
Hero.h
#pragma once
#include "Character.h"
#include <string>
using namespace std;
class Hero :
public Character
{
public:
Hero(string name, int hp);
}
Hero.cpp
#include "Hero.h"
#include <iostream>
Hero::Hero(string name, int hp)
: Character(name, "Hero", hp)
{
}
Ability.h
#pragma once
#include <string>
#include "Character.h"
using namespace std;
class Ability
{
public:
Ability(string name, string type, Character* owner);
void levelUp();
private:
string name;
string type;
int level;
Character* owner;
}
Ability.cpp
#include "Ability.h"
Ability::Ability(string name, string type, Character* owner)
{
this->name = name;
this->type = type;
this->owner = owner;
level = 1;
}
void Ability::levelUp(){
level++;
}
NormalAbility.h
#pragma once
#include "Ability.h"
#include <string>
using namespace std;
class NormalAbility :
public Ability
{
public:
NormalAbility(string name);
}
NormalAbility.cpp
#pragma once
#include "NormalAbility.h"
#include <string>
using namespace std;
NormalAbility::NormalAbility(string name) : Ability(name, "Normal")
{
//some codes
}
This way you avoid the circular include of the .h files, because you're including it in the .cpp, and in the .h you're saying that, "Character exists but don't care about his definition right now"
Ability.h
#pragma once
#include <string>
class Character;
using namespace std;
class Ability
{
public:
Ability(string name, string type, Character* owner);
void levelUp();
private:
string name;
string type;
int level;
Character* owner;
}
Ability.cpp
#include "Ability.h"
#include "Character.h"
Ability::Ability(string name, string type, Character* owner)
{
this->name = name;
this->type = type;
this->owner = owner;
level = 1;
}
void Ability::levelUp(){
level++;
}