我收到错误"无效使用不完整的类型'class map'

I'm getting an error "invalid use of incomplete type 'class map'

本文关键字:类型 map class 用不完 错误 无效      更新时间:2023-10-16

我正在制作一个基本的基于文本的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() {
}