C++ 我收到错误“不完整类型‘类映射’的无效使用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20013901/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 22:51:53  来源:igfitidea点击:

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

c++

提问by user2998425

I am making a basic text based RPG sorry if my question is stupid because im new to c++. So basically I have a small combat class that i have to link back and forth to from the map class so I had to forward declare my map class and it comes up with the error. BTW sorry there aren't any comments.

如果我的问题很愚蠢,我正在制作一个基于文本的基本 RPG 抱歉,因为我是 C++ 新手。所以基本上我有一个小的战斗类,我必须从地图类来回链接,所以我不得不转发声明我的地图类,它出现了错误。BTW 抱歉,没有任何评论。

Here is the error: invalid use of incomplete type class Map

这是错误: 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 appeared\n";
        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 killed\n";
                    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 deal\n";
                cout <<damagedealt<<" points of damage your health is\n";
                cout <<playerobj.health;
                if (playerobj.health>0)
                {
                    this->newturn();
                }
                else if (playerobj.health<=0)
                {
                    cout <<playerobj.name<<"was killed\n";
                    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:
    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 the\n";
        cout <<"mouth of a mighty river to the north\n";
        cout <<"What do you want to do?\n";


    }


    void relaypointb()
    {
    playerobj.location=="relaypointb";
    cout << "\n\n%%%%%%%%%%%%%%%%%%%%\n";
    cout << "%                  %\n";
    cout << "%   #Wild North#   %\n";
    cout << "%                  %\n";
    cout << "%%%%%%%%%%%%%%%%%%%%\n\n";
    cout <<"You have entered the wild north this is where your journey starts\n";
    cout <<"What would you like to do\n\n";
    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 command\n\n";
            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;
    }
};

回答by Adam

Your first usage of Mapis inside a function in the combatclass. That happens before Mapis defined, hence the error.

您的第一次使用Map是在combat类中的函数内。这发生在Map定义之前,因此出现错误。

A forward declaration only says that a particular class will be defined later, so it's ok to reference it or have pointers to objects, etc. However a forward declaration does not say what members a class has, so as far as the compiler is concerned you can't use any of them until Mapis fully declared.

前向声明仅表示稍后将定义特定类,因此可以引用它或具有指向对象的指针等。但是,前向声明并未说明类具有哪些成员,因此就编译器而言,您Map在完全声明之前不能使用它们中的任何一个。

The solution is to follow the C++ pattern of the class declaration in a .hfile and the function bodies in a .cpp. That way all the declarations appear before the first definitions, and the compiler knows what it's working with.

解决方案是遵循.h文件中的类声明和.cpp. 这样所有的声明都出现在第一个定义之前,编译器知道它在使用什么。

回答by Kemin Zhou

I am just providing another case where you can get this error message. The solution will be the same as Adam has mentioned above. This is from a real code and I renamed the class name.

我只是提供另一种情况,您可以在其中收到此错误消息。解决方案将与亚当上面提到的相同。这是来自一个真实的代码,我重命名了类名。

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;
};

The above will no pass the compiler and get error: invalid use of incomplete type FooReaderPrivate. You basically have to put the inline portion into the *.cpp implementation file. This is OK. What I am trying to say here is that you may have a design issue. Cross reference of two classes may be necessary some cases, but I would say it is better to avoid them at the start of the design. I would be wrong, but please comment then I will update my posting.

以上不会通过编译器并得到错误:无效使用不完整类型 FooReaderPrivate。您基本上必须将内联部分放入 *.cpp 实现文件中。还行吧。我在这里想说的是你可能有一个设计问题。在某些情况下可能需要交叉引用两个类,但我认为最好在设计开始时避免它们。我错了,但请发表评论,然后我会更新我的帖子。