Я пытаюсь изучить C ++, и в настоящее время я пытаюсь узнать, как реализовать композицию объектов на этом языке.
у меня есть Character
класс, который наследуется Hero
и Monster
учебный класс.
Character
имеет NormalAbility
и SpecialAbility
,
Я сделал NormalAbility
а также SpecialAbility
классы и оба наследуют Ability
суперкласс.
Моя проблема в том, что когда я помещаю #include «Character.h» в Ability.h, переменные normalAbility и specialAbility в Character.h
не получить признание их уважаемых классов. Ошибки, такие как «синтаксическая ошибка: строка идентификатора», отображаются в заголовках обоих унаследованных классов Ability.
Вот мой код:
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
}
Таким образом, вы избегаете циклического включения файлов .h, потому что вы включаете его в .cpp, а в .h вы говорите, что «персонаж существует, но сейчас его не волнует его определение»
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++;
}