Подтвердить что ты не робот

Я получаю сообщение об ошибке "неверное использование неполного типа" map 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 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;
    }
};
4b9b3361

Ответ 1

Ваше первое использование Map внутри функции в классе combat. Это происходит до того, как определен Map, поэтому возникает ошибка.

Прямое объявление только говорит, что определенный класс будет определен позже, так что можно ссылаться на него или иметь указатели на объекты и т.д. Однако предварительное объявление не говорит, какие члены есть в классе, насколько это касается компилятора. не может использовать ни один из них, пока Map не будет полностью объявлен.

Решение состоит в том, чтобы следовать шаблону C++ объявления класса в файле .h и телам функций в .cpp. Таким образом, все объявления появляются перед первыми определениями, и компилятор знает, с чем он работает.

Ответ 2

Я просто предоставляю другой случай, когда вы можете получить это сообщение об ошибке. Решение будет таким же, как упомянул Адам. Это из реального кода, и я переименовал имя класса.

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. Хорошо. То, что я пытаюсь сказать здесь, состоит в том, что у вас может возникнуть проблема с дизайном. В некоторых случаях может потребоваться перекрестная ссылка двух классов, но я бы сказал, что лучше избегать их в начале проектирования. Я был бы неправ, но, пожалуйста, прокомментируйте, тогда я обновлю свое сообщение.