我收到错误"无效使用不完整的类型'class map'
I'm getting an error "invalid use of incomplete type 'class map'
我正在制作一个基本的基于文本的RPG,如果我的问题很愚蠢,因为我是C ++的新手。所以基本上我有一个小的战斗类,我必须从地图类来回链接,所以我不得不转发声明我的地图类,它出现了错误。顺便说一句,对不起,没有任何评论。
这是错误:invalid use of incomplete type class Map
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
class Map;
class Player
{
public:
int health;
int damage;
int defense;
int gems=0;
string race;
string name;
string location;
};
class Enemy
{
public:
int ehealth;
int edamage;
int edefense;
int echoice;
};
class combat
{
public:
Map* mapobj;
int damagedealt;
Player playerobj;
Enemy enemeyobj;
string cchoice;
string retry;
void initial()
{
cout <<"A wild orc has appearedn";
cout <<"What do you do?n";
cout <<"---------------------------n";
cout <<"|-------------------------|n";
cout <<"|----Attack-----Defend----|n";
cout <<"|-------------------------|n";
cout <<"---------------------------n";
cin >>cchoice;
this->battle();
};
void newturn()
{
cout <<"The orc is still alive!";
cout <<"What do you do?";
cout <<"n---------------------------n";
cout <<"|-------------------------|n";
cout <<"|----Attack-----Defend----|n";
cout <<"|-------------------------|n";
cout <<"---------------------------n";
cin >>cchoice;
this->battle();
};
void battle()
{
enemeyobj.echoice = rand() % 2;
if (enemeyobj.echoice= 1)
{
if (cchoice=="Attack")
{
playerobj.damage;
enemeyobj.ehealth=enemeyobj.ehealth-playerobj.damage;
cout <<"You did "<<playerobj.damage<<" points of damge to the enemey.n";
if (enemeyobj.ehealth>0)
{
playerobj.health=enemeyobj.edamage-playerobj.health;
cout <<"The enemyattacked you. You now have "<<playerobj.health<<" health";
if (playerobj.health>0)
{
this->newturn();
}
else if (playerobj.health<=0)
{
cout << playerobj.name << "was killedn";
cout << "Game Over";
}
}
else if (enemeyobj.ehealth<=0)
{
cout <<"You have defeated the orc!";
if (playerobj.location=="a")
{
mapobj->relaypointa();
}
}
}
else if (cchoice=="Defend")
{
damagedealt=enemeyobj.edamage-playerobj.defense;
playerobj.health=damagedealt-playerobj.health;
cout <<"You defend but the enemey was able to dealn";
cout <<damagedealt<<" points of damage your health isn";
cout <<playerobj.health;
if (playerobj.health>0)
{
this->newturn();
}
else if (playerobj.health<=0)
{
cout <<playerobj.name<<"was killedn";
cout <<"Game Over";
}
}
}
else if (enemeyobj.echoice=2)
{
if (cchoice=="Attack")
{
damagedealt=enemeyobj.edefense-playerobj.damage;
enemeyobj.ehealth=enemeyobj.ehealth-damagedealt;
cout <<"You did "<<damagedealt<<" points of damage to the enemy";
if (enemeyobj.ehealth>0)
{
this->newturn();
}
else if (enemeyobj.ehealth<=0)
{
cout <<"You have defeated the orc!";
mapobj->relaypointa();
}
}
else if (cchoice=="Defend")
{
cout <<"Both parties defended";
this->newturn();
}
}
}
};
class Map
{
public:
combat combatobj;
string mchoice;
int espawn;
Player playerobj;
Enemy enemeyobj;
void relaypointaespawn()
{
playerobj.location=="relaypointa";
enemeyobj.ehealth = rand() % 50 + 100;
enemeyobj.edamage = rand() % 50 + 75;
enemeyobj.edefense = rand() % 50 + 50;
combatobj.initial();
}
void relaypointa()
{
cout <<"You have found yourself at then";
cout <<"mouth of a mighty river to the northn";
cout <<"What do you want to do?n";
}
void relaypointb()
{
playerobj.location=="relaypointb";
cout << "nn%%%%%%%%%%%%%%%%%%%%n";
cout << "% %n";
cout << "% #Wild North# %n";
cout << "% %n";
cout << "%%%%%%%%%%%%%%%%%%%%nn";
cout <<"You have entered the wild north this is where your journey startsn";
cout <<"What would you like to donn";
cin >> mchoice;
if (mchoice=="Travel")
{
cout <<"Where would you like to travel?n";
cin >>mchoice;
if (mchoice=="North")
{
}
else if (mchoice=="East")
{
}
else if (mchoice=="South")
{
}
else if (mchoice=="West")
{
this->relaypointaespawn();
}
else
{
cout <<"Invalid commandnn";
this->relaypointb();
}
}
}
void relaypointcespawn()
{
playerobj.location=="a";
enemeyobj.ehealth = rand() % 50 + 100;
enemeyobj.edamage = rand() % 50 + 75;
enemeyobj.edefense = rand() % 50 + 50;
espawn = rand() % 2;
}
};
Map
的第一次用法是在combat
类的函数中。这发生在定义Map
之前,因此会出现错误。
前向声明只说稍后将定义特定类,因此可以引用它或具有指向对象的指针等。但是,前向声明不会说明类具有哪些成员,因此就编译器而言,在完全声明Map
之前,您不能使用其中任何一个。
解决方案是遵循 .h
文件中的类声明和.cpp
中的函数体的C++模式。这样,所有声明都出现在第一个定义之前,编译器知道它在处理什么。
我只是提供了另一种情况,您可以在其中收到此错误消息。 解决方案将与亚当上面提到的相同。这是来自一个真实的代码,我重命名了类名。
class FooReader {
public:
/** Constructor */
FooReader() : d(new FooReaderPrivate(this)) { } // will not compile here
.......
private:
FooReaderPrivate* d;
};
====== In a separate file =====
class FooReaderPrivate {
public:
FooReaderPrivate(FooReader*) : parent(p) { }
private:
FooReader* parent;
};
以上不会通过编译器并得到错误:无效使用不完整的类型FooReaderPrivate。 基本上,您必须将内联部分放入 *.cpp 实现文件中。这没关系。 我在这里想说的是,你可能有一个设计问题。 在某些情况下,两个类的交叉引用可能是必要的,但我想说最好在设计开始时避免它们。 我会错的,但请发表评论,然后我会更新我的帖子。
这是因为您需要显示函数的至少递减。
对于解决方法,请使用映射类的纯虚拟方法创建接口类。 声明您正在使用的函数(因为我只看到 relaypointa),然后将此接口类放在文件的开头,当然不要忘记从中派生映射并使用指向接口的指针。 战斗类将看到界面和纯虚函数, 所以会没事的。
当我想使用单页在线编译器时,我看到这个问题
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
class MapIf {
public:
virtual void relaypointa() = 0;
};
class Player {
public:
int health;
int damage;
int defense;
int gems = 0;
string race;
string name;
string location;
};
class Enemy {
public:
int ehealth;
int edamage;
int edefense;
int echoice;
};
class combat {
public:
MapIf * mapobj;
int damagedealt;
Player playerobj;
Enemy enemeyobj;
string cchoice;
string retry;
void initial() {
cout << "A wild orc has appearedn";
cout << "What do you do?n";
cout << "---------------------------n";
cout << "|-------------------------|n";
cout << "|----Attack-----Defend----|n";
cout << "|-------------------------|n";
cout << "---------------------------n";
cin >> cchoice;
this -> battle();
}
void newturn() {
cout << "The orc is still alive!";
cout << "What do you do?";
cout << "n---------------------------n";
cout << "|-------------------------|n";
cout << "|----Attack-----Defend----|n";
cout << "|-------------------------|n";
cout << "---------------------------n";
cin >> cchoice;
this -> battle();
};
void battle() {
enemeyobj.echoice = rand() % 2;
if (enemeyobj.echoice = 1) {
if (cchoice == "Attack") {
playerobj.damage;
enemeyobj.ehealth = enemeyobj.ehealth - playerobj.damage;
cout << "You did " << playerobj.damage << " points of damge to the enemey.n";
if (enemeyobj.ehealth > 0) {
playerobj.health = enemeyobj.edamage - playerobj.health;
cout << "The enemyattacked you. You now have " << playerobj.health << " health";
if (playerobj.health > 0) {
this -> newturn();
} else if (playerobj.health <= 0) {
cout << playerobj.name << "was killedn";
cout << "Game Over";
}
} else if (enemeyobj.ehealth <= 0) {
cout << "You have defeated the orc!";
if (playerobj.location == "a") {
mapobj -> relaypointa();
}
}
} else if (cchoice == "Defend") {
damagedealt = enemeyobj.edamage - playerobj.defense;
playerobj.health = damagedealt - playerobj.health;
cout << "You defend but the enemey was able to dealn";
cout << damagedealt << " points of damage your health isn";
cout << playerobj.health;
if (playerobj.health > 0) {
this -> newturn();
} else if (playerobj.health <= 0) {
cout << playerobj.name << "was killedn";
cout << "Game Over";
}
}
} else if (enemeyobj.echoice = 2) {
if (cchoice == "Attack") {
damagedealt = enemeyobj.edefense - playerobj.damage;
enemeyobj.ehealth = enemeyobj.ehealth - damagedealt;
cout << "You did " << damagedealt << " points of damage to the enemey";
if (enemeyobj.ehealth > 0) {
this -> newturn();
} else if (enemeyobj.ehealth <= 0) {
cout << "You have defeated the orc!";
mapobj -> relaypointa();
}
} else if (cchoice == "Defend") {
cout << "Both parties defended";
this -> newturn();
}
}
}
};
class Map: public MapIf {
public: combat combatobj;
string mchoice;
int espawn;
Player playerobj;
Enemy enemeyobj;
void relaypointaespawn() {
playerobj.location == "relaypointa";
enemeyobj.ehealth = rand() % 50 + 100;
enemeyobj.edamage = rand() % 50 + 75;
enemeyobj.edefense = rand() % 50 + 50;
combatobj.initial();
}
void relaypointa() {
cout << "You have found yourself at then";
cout << "mouth of a mighty river to the northn";
cout << "What do you want to do?n";
}
void relaypointb() {
playerobj.location == "relaypointb";
cout << "nn%%%%%%%%%%%%%%%%%%%%n";
cout << "% %n";
cout << "% #Wild North# %n";
cout << "% %n";
cout << "%%%%%%%%%%%%%%%%%%%%nn";
cout << "You have entered the wild north this is where your journey startsn";
cout << "What would you like to donn";
cin >> mchoice;
if (mchoice == "Travel") {
cout << "Where would you like to travel?n";
cin >> mchoice;
if (mchoice == "North") {
} else if (mchoice == "East") {
} else if (mchoice == "South") {
} else if (mchoice == "West") {
this -> relaypointaespawn();
} else {
cout << "Invalid commandnn";
this -> relaypointb();
}
}
}
void relaypointcespawn() {
playerobj.location == "a";
enemeyobj.ehealth = rand() % 50 + 100;
enemeyobj.edamage = rand() % 50 + 75;
enemeyobj.edefense = rand() % 50 + 50;
espawn = rand() % 2;
}
};
int main() {
}
- 使用模板化的键类型定义 std::map,该键类型基于作为参数接收的函数
- 如何使用 uint64_t 键类型从 std::map<int, std::string> 返回值?
- 类型为 'std::map< char,int > 的 <Swig 对象的代理
- std::map 保存任何值类型
- 标准::map键类型的严格弱排序概念
- 如何在 Visual C++ 中从返回类型为 map 的函数返回 null?
- 在变量名后声明带有 () 的非内部类型与不使用变量名的行为不同。即 std::map<int,char>x(); - 这是怎么回事?
- 将参数列表未知的可变参数模板类型定义为 std::map 值类型
- 不完整的类型为 std::map 的成员
- 当 map 是一个整数数组并且由 operator[] 创建时,它是否初始化其映射类型
- 具有 std::map 和 std::variant 的不完整类型
- 如何在 c++ 中使用返回类型导出函数 std::map
- 错误:与'operator='不匹配(操作数类型为"std::map<int、double>::iterator
- 为什么C++允许类型没有 std::map 的默认构造函数,而没有 std::p air
- 将QML数组和MAP/对象类型与C 区分开
- std::map使用不同的数据类型进行值
- 为什么缩小转换范围不能防止错误类型的map.insert()失败
- Qt nmake:错误 C3203:"map":非专用类模板不能用作模板参数"base"的模板参数,预期为真实类型
- 无法使用 std::map 推断 lambda 的返回类型
- 如何打印这种类型map的值map
, int>关联[2]