前向声明覆盖完整定义
Forward declaration overriding full definition
我知道有一些题目是前向声明的,但是看了之后好像不太符合这种情况。我通常明白发生了什么,需要一个完整的定义来分配。但是,我真的认为我在这里有一个完整的定义,所以我很困惑。
//game.h
#include "wizard.h"
#include "warrior.h"
#include "archer.h"
#include "fighter.h"
#ifndef GAME_H
#define GAME_H
enum movetype{
BOOST,
ATTACK,
SPECIAL,
SHIELD
};
struct move{
enum movetype type;
fighter * source;
fighter * target;
};
class game{
public:
game();
~game();
void execmove(move&);
bool trymove();
private:
bool turn;
fighter* t1 [3];
fighter* t2 [3];
};
#endif
所以在游戏中我包括所有其他 类
在fighter中我转发宣告warrior:
//fighter.h
#ifndef FIGHTER_H
#define FIGHTER_H
class fighter;
class warrior;
struct link {
fighter * warrior;
fighter * target;
};
class fighter{
private:
public:
fighter();
virtual ~fighter();
void action(int, fighter*);
virtual void special(fighter*);
void attack(fighter*);
void defend();
void tick();
void damage(int,int);
void createLink(warrior *);
void removeLink();
protected:
int hp;
int priority;
int boosts;
int shields;
bool alive;
struct link l;
};
#endif
但是当我尝试在游戏中分配战士时:
//game.cpp
#include <iostream>
#include "game.h"
game::game()
{
t1[0] = new warrior();
t1[1] = new wizard();
t1[2] = new archer();
t2[0] = new warrior();
t2[2] = new archer();
t2[1] = new wizard();
}
game::~game()
{
for(int i = 0; i<3; i++)
{
delete t1[i];
delete t2[i];
}
}
void game::execmove(move& m)
{
}
我得到:
game.cpp:9:14: error: allocation of incomplete type 'warrior'
t1[0] = new warrior();
^~~~~~~
./fighter.h:7:7: note: forward declaration of 'warrior'
class warrior;
^
game.cpp:13:14: error: allocation of incomplete type 'warrior'
t2[0] = new warrior();
^~~~~~~
./fighter.h:7:7: note: forward declaration of 'warrior'
class warrior;
似乎我前向声明的事实让编译器忽略了我还包括了完整定义的事实,这真的很奇怪。我想知道是否缺少某些东西,因为如果前向声明使完整定义被忽略,我不知道如何修复它。
底线:既然我在 game.h 中包含了完整的 warrior.h 文件,为什么我不能分配 warrior?
这里是warrior.h:
#include "fighter.h"
#ifndef FIGHTER_H
#define FIGHTER_H
class warrior{
public:
warrior();
~warrior();
void special(fighter);
private:
};
#endif
将 warrior.h 更改为:(即正确包含守卫)
#ifndef WARRIOR_H
#define WARRIOR_H
#include "fighter.h"
class warrior{
public:
warrior();
~warrior();
void special(fighter);
private:
};
#endif
如果支持,最好还是使用 #pragma once
错误命名的守卫导致它不包括 warrior 文件。谢谢@1201ProgramAlarm
不同的.h文件需要使用不同的include guard符号。
"fighter.h" 定义 FIGHTER_H
,因此当在 "warrior.h" 中遇到 #if 检查时,将跳过 class warrior
的定义。
我知道有一些题目是前向声明的,但是看了之后好像不太符合这种情况。我通常明白发生了什么,需要一个完整的定义来分配。但是,我真的认为我在这里有一个完整的定义,所以我很困惑。
//game.h
#include "wizard.h"
#include "warrior.h"
#include "archer.h"
#include "fighter.h"
#ifndef GAME_H
#define GAME_H
enum movetype{
BOOST,
ATTACK,
SPECIAL,
SHIELD
};
struct move{
enum movetype type;
fighter * source;
fighter * target;
};
class game{
public:
game();
~game();
void execmove(move&);
bool trymove();
private:
bool turn;
fighter* t1 [3];
fighter* t2 [3];
};
#endif
所以在游戏中我包括所有其他 类 在fighter中我转发宣告warrior:
//fighter.h
#ifndef FIGHTER_H
#define FIGHTER_H
class fighter;
class warrior;
struct link {
fighter * warrior;
fighter * target;
};
class fighter{
private:
public:
fighter();
virtual ~fighter();
void action(int, fighter*);
virtual void special(fighter*);
void attack(fighter*);
void defend();
void tick();
void damage(int,int);
void createLink(warrior *);
void removeLink();
protected:
int hp;
int priority;
int boosts;
int shields;
bool alive;
struct link l;
};
#endif
但是当我尝试在游戏中分配战士时:
//game.cpp
#include <iostream>
#include "game.h"
game::game()
{
t1[0] = new warrior();
t1[1] = new wizard();
t1[2] = new archer();
t2[0] = new warrior();
t2[2] = new archer();
t2[1] = new wizard();
}
game::~game()
{
for(int i = 0; i<3; i++)
{
delete t1[i];
delete t2[i];
}
}
void game::execmove(move& m)
{
}
我得到:
game.cpp:9:14: error: allocation of incomplete type 'warrior'
t1[0] = new warrior();
^~~~~~~
./fighter.h:7:7: note: forward declaration of 'warrior'
class warrior;
^
game.cpp:13:14: error: allocation of incomplete type 'warrior'
t2[0] = new warrior();
^~~~~~~
./fighter.h:7:7: note: forward declaration of 'warrior'
class warrior;
似乎我前向声明的事实让编译器忽略了我还包括了完整定义的事实,这真的很奇怪。我想知道是否缺少某些东西,因为如果前向声明使完整定义被忽略,我不知道如何修复它。
底线:既然我在 game.h 中包含了完整的 warrior.h 文件,为什么我不能分配 warrior?
这里是warrior.h:
#include "fighter.h"
#ifndef FIGHTER_H
#define FIGHTER_H
class warrior{
public:
warrior();
~warrior();
void special(fighter);
private:
};
#endif
将 warrior.h 更改为:(即正确包含守卫)
#ifndef WARRIOR_H
#define WARRIOR_H
#include "fighter.h"
class warrior{
public:
warrior();
~warrior();
void special(fighter);
private:
};
#endif
如果支持,最好还是使用 #pragma once
错误命名的守卫导致它不包括 warrior 文件。谢谢@1201ProgramAlarm
不同的.h文件需要使用不同的include guard符号。
"fighter.h" 定义 FIGHTER_H
,因此当在 "warrior.h" 中遇到 #if 检查时,将跳过 class warrior
的定义。