多个文件中的标题保护,它们都相互依赖,我有两个以上的HPP文件需要彼此

时间:2014-03-22 16:07:59

标签: c++ file include

我在gooogle上搜索了将近4天,每天几个小时,没有结果。我不希望它达到这一点,但我真的找不到任何东西。 现在,我将描述我的问题 - 询问您是否需要澄清:

问题:我有3个HPP文件,这些文件是EACHOTHER的循环, 除了避免" #include嵌套太深"并且标题后卫根本没有帮助。问题。但现在我收到以下错误:' forest'未在此范围内声明

#ifndef MAINMENU_HPP
#define MAINMENU_HPP
#include <iostream>
#include <windows.h>
#include <fstream>
#include <string>
#include <stdlib.h>
#include <time.h>
using namespace std;

#ifndef MAINMENU_HPP
#include "Areas.hpp"
Areas areas;
#endif
#include "Player.hpp"

#include "SetColor.hpp"
void mainMenu();


void mainMenu()
{
    int action;
    //battle();
    initPlayer();
    if(player.xp >= player.xpRequired)
        {
            player.xp -= player.xpRequired;
            player.lvl += 1;
            SetColor(14);
            cout << endl << "_-*You have leveled up!*-_" << endl << endl;
            SetColor(7);
            player.xpRequired = 40 + player.lvl * 10 * player.lvl;
            levelUp();
        }
    player.damageModifier = 5 + player.strength/2;
    player.baseDamage = 5 + player.strength/2;

    cout << "=================================City of Town==================================" << endl;
    cout << "Made by Erik aka Einar aka NukeTester and Mr.WertyQaz" << endl;
    cout << "Enter [0] to quit" << endl;
    cout << "Enter [1] to view stats" << endl;
    cout << "Enter [2] to go to the forest" << endl;
    cout << "Enter [3] to save the game" << endl;
    cin >> action;

    switch (action)
        {
        case 0:
            //quit();
            break;
        case 1:
        player.xp = 400;
        cout << player.playerName << "'s Inventory " << endl;
        cout << "Health: ";
        SetColor(13);
        cout << player.health;
        SetColor(7);
        cout << "/";
        SetColor(13);
        cout << player.maxHealth << endl;
        SetColor(7);
        cout << "Gold: ";
        SetColor(14);
        cout << player.money;
        SetColor(7);
        cout << endl;
        cout << "Experience: ";
        SetColor(3);
        cout << player.xp;
        SetColor(7);
        cout << "/" ;
        SetColor(3);
        cout << player.xpRequired << endl;
        SetColor(7);
        cout << "Level: ";
        SetColor(2);
        cout << player.lvl << endl;
        SetColor(7);
        cout << "Strength: " << player.strength << endl;
        cout << "Dexterity: " << player.dexterity << endl;
        cout << "Vitality: " << player.vitality << endl;
        cout << "Speed: " << player.speed << endl;
        system("PAUSE");
        system("CLS");
        mainMenu();
        break;
        case 2:
        forest(); // THIS IS THE ERROR
        break;
        }
        }
#endif

//Areas.hpp (Where forest lays)
#ifndef MAINMENU_HPP
#include "MainMenu.hpp"
MainMenu menu;
#endif

#ifndef AREAS_HPP
#define AREAS_HPP

#include <iostream>
#include <windows.h>
#include <fstream>
#include <string>
#include <stdlib.h>
#include <time.h>

#include "SetColor.hpp"

using namespace std;


void battle();
void forest();


void battle()
{
    int action;
    system("CLS");
    srand (time(NULL));
  /* generate secret number between 1 and 10: */
    int monster;
    monster = rand() % 2 + 1;

    goblin.enemyID = monster;
    if(goblin.enemyID == 1)
{
    goblin.enemyName = "Goblin";
    goblin.dead = false;
    goblin.enemyID = 1;
    goblin.health = 33;
    goblin.baseDamage = 3;
    goblin.damageModifier = 5;

    srand (time(NULL));
    goblin.damage = rand() % goblin.damageModifier + goblin.baseDamage;

    srand (time(NULL));
    goblin.money = rand() % 5 + 10;
    cout << "====================================BATTLE======================================";
    cout << "Opponent: " << goblin.enemyName << endl;
    cout << "It's health is: " << goblin.health << endl;
    cout << "Do you want to battle it?" << endl;
    cout << "Enter [1] for yes" << endl << "Enter [2] for no" << endl;

    cin >> action;
        if(action == 1)
        {
            BattleGoblin:
                    if(player.health <=0)
        {
            player.dead = true;
        }
    if(player.dead){
            cout << "You have died! Game Over!" << endl;
            cout << "Press Enter to continue..." << endl;
            system("PAUSE");
            //quit();
    }
            cout << "Enter [3] for a quick heal" << endl;
            cin >> action;
            if(action == 3)
                {
                    player.health = player.maxHealth;
                    goto BattleGoblin;
                }
    if(action == 1)
        {
            //Player Damage

            player.damage = rand() % player.damageModifier + player.baseDamage;
            goblin.health -= player.damage;

            cout << "You deal ";
            SetColor(4);
            cout << player.damage;
            SetColor(7);
            cout << " damage to the evil Goblin!" << endl;
            cout << "Goblin health: " << goblin.health << endl;

            //Goblin Damage
            if(goblin.health >0)
                {
            srand (time(NULL));
            goblin.damage = rand() % goblin.damageModifier + goblin.baseDamage;

            cout << "Goblin strikes you, dealing " << goblin.damage << " damage!" << endl;
            player.health -= goblin.damage;
            cout << "Your health: ";
            SetColor(13);
            cout << player.health << endl;
            SetColor(7);
            system("PAUSE");
            system("CLS");
            }
            else if(goblin.health <=0)
        {
            SetColor(2);
            cout << "Goblin is now DEAD!" << endl;
            SetColor(7);
            system("PAUSE");
            system("CLS");
            goblin.dead = true;
        }
      if(goblin.dead)
        {
            cout << "You killed the greedy Goblin!" << endl;
            cout << "You have earned " << goblin.money << " Gold Coins!" << endl;
            cout << "You have also gained a total 5 experience from the Goblin!" << endl;
            player.money += goblin.money;
            player.xp += 5;
            system("PAUSE");
            menu.mainMenu();
        }
            goto BattleGoblin;
            }
        }
        if(action == 2)
        {
            srand(time(NULL));
            int fleeOpponent = rand () % 4 + 1;

        if(fleeOpponent >=2)
        {
            cout << "You flee the evil Goblin. " << endl;
            system("PAUSE");
            system("CLS");
            mainMenu();
        }
        else if (fleeOpponent == 1)
        {
            cout << "The evil Goblin catches you, before you get away, and deals 5 damage!" << endl;
            player.health -= goblin.damage;
            goto BattleGoblin;
        }

            cout << "You flee the evil Goblin. " << endl;
            system("PAUSE");
            system("CLS");
            mainMenu();
        }
        if(action > 2)
            {
                cout << "Undefined action. Press Enter.";
                cin.get();
                goto BattleGoblin;
            }
}


//=========================================================================================================================================================================================


    orc.enemyID = monster;
    if(orc.enemyID == 2)
    {
    orc.enemyName = "Orc";
    orc.dead = false;
    orc.enemyID = 1;
    orc.health = 140;
    orc.baseDamage = 7;
    orc.damageModifier = 8;

    srand(time(NULL));
    orc.damage = rand() % orc.damageModifier + orc.baseDamage;

    srand (time(NULL));
    orc.money = rand() % 7 + 3;
    cout << "====================================BATTLE======================================";
    cout << "Opponent: " << orc.enemyName << endl;
    cout << "It's health is: " << orc.health << endl;
    cout << "Do you want to battle it?" << endl;
    cout << "Enter [1] for yes" << endl << "Enter [2] for no" << endl;
    cin >> action;
    if(action == 1)
        {
            BattleOrc:
                    if(player.health <=0)
        {
            player.dead = true;
        }
    if(player.dead){
            cout << "You have died! Game Over!" << endl;
            cout << "Press Enter to continue..." << endl;
            cin.get();
            //quit();
    }
            cout << "Enter [1] for attack" << endl;
            cout << "Enter [3] for a quick heal" << endl;
            cin >> action;
            if(action == 3)
                {
                    player.health = player.maxHealth;
                    goto BattleOrc;
                }
    if(action == 1)
        {
            player.damage = rand() % player.damageModifier + player.baseDamage;
            orc.health -= player.damage;

            cout << "You deal ";
            SetColor(4);
            cout << player.damage;
            SetColor(7);
            cout << " damage to the evil Orc!" << endl;
            cout << "Orc health: " << orc.health << endl;

            srand(time(NULL));
            orc.damage = rand() % orc.damageModifier + orc.baseDamage;
            if(orc.health >0)
                {
            cout << "Orc strikes you, dealing " << orc.damage << " damage!" << endl;
            player.health -= orc.damage;
            cout << "Your health: " << player.health << endl;
            system("PAUSE");
            system("CLS");
                }
                else if(orc.health <=0)
        {
            SetColor(2);
            cout << "Orc is now dead!" << endl;
            SetColor(7);
            system("PAUSE");
            system("CLS");
            orc.dead = true;
        }
      if(orc.dead)
        {
            cout << "You killed the ferocius Orc!" << endl;
            cout << "You have earned " << orc.money << " Gold Coins!" << endl;
            cout << "You have also gained a total 21 experience from the Orc!" << endl;
            player.money += orc.money;
            player.xp += 21;
            system("PAUSE");
            mainMenu();
        }
            goto BattleOrc;
            }
        }
     if(action == 2)
        {
            srand(time(NULL));
            int fleeOpponent = rand () % 4 + 1;

        if(fleeOpponent >=2)
        {
            cout << "You flee the evil Orc. " << endl;
            system("PAUSE");
            system("CLS");
            mainMenu();
        }
        else if (fleeOpponent == 1)
        {
            cout << "The evil Orc catches you, before you get away, and deals 5 damage!" << endl;
            player.health -= orc.damage;
            goto BattleOrc;
        }

            cout << "You flee the evil Orc. " << endl;
            system("PAUSE");
            system("CLS");
            mainMenu();
        }
        if(action > 3)
            {
                cout << "Undefined action. Press Enter.";
                cin.get();
                goto BattleOrc;
            }
}
}



void forest()
{

    int action;
    system("CLS");
    cout << "===================================FOREST=======================================";
    cout << "Enter [0] to go back to town" << endl,
    cout << "Enter [1] to chop some wood" << endl;
    cout << "Enter [2] to go for a walk. Might be risky..." << endl;

    cin >> action;
    if(action == 0)
        {
//            mainMenu();
        }
    if(action == 1 && player.hasHatchet)
        {
            cout << "you cut some wood.";
            system("PAUSE");
            system("CLS");
//            mainMenu();
        }

        else if(action == 1)
            {
                cout << "You can't chop trees without a hatchet! Go buy one at the blacksmith!" << endl;
                system("PAUSE");
                system("CLS");
//                mainMenu();
            }
    if(action == 2)
        {
            srand (time(NULL));
            int forestBattle;
            forestBattle = rand() % 10 + 1;
            if(forestBattle >=1 && forestBattle <=5)
                {
                    cout << "You walk into the forest." << endl << "All you found was peace. You decide to head back to town." << endl << endl;
                    system("PAUSE");
                    system("CLS");
//                    mainMenu();
                }
                if(forestBattle >=5 && forestBattle <10)
                    {
                        cout << "Something is heading towards you!" << endl;
                        system("PAUSE");
                        system("CLS");
                        //battle();

                    }
            if(forestBattle == 10)
                {
                    cout << "You found some fresh apples laying on the ground. You eat the apples and gain +1 health." << endl << endl;
                player.health += 1;
                system("PAUSE");
                system("CLS");
//                mainMenu();
                }
        }
}

#endif

//main.cpp
#ifndef MAINMENU_HPP
#include "MainMenu.hpp"

#endif
//#endif // MAINMENU_HPP
#include <iostream>
#include <windows.h>
#include <fstream>
#include <string>
#include <stdlib.h>
#include <time.h>
#include "Player.hpp"
#include "MainMenu.hpp"

using namespace std;

int action = 0;


int quit();
void matchMaking();
void battle();
void saveGame();
void setColor();

int quit()
{
    exit(1);
}

void matchMaking()
{

}


void saveGame()
{
    std::string saveName = "save";

    cout << "Enter savegame name: ";
    std::getline(std::cin, saveName);
    ofstream save(saveName.c_str());
    save << "Health: " << player.health << endl << "Damage: " << player.damage << endl << "Gold: "  << player.money << endl << endl;
}


int main()
{
//Initialize functions
    initPlayer();
    mainMenu();

//Initialize local variables
/*
v1 = rand() % 100;         // v1 in the range 0 to 99
v2 = rand() % 100 + 1;     // v2 in the range 1 to 100
v3 = rand() % 30 + 1985;   // v3 in the range 1985-2014
*/
}

//Strangest thing of all, because this is included in different files more than twice, but
//this works fine! I don't have any idea why.
#ifndef SETCOLOR_HPP
#define SETCOLOR_HPP

#include <iostream>
#include <windows.h>
#include <fstream>
#include <string>
#include <stdlib.h>
#include <time.h>

//#include "Player.hpp"

using namespace std;

void SetColor(int value);

void SetColor(int value)
{
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),  value);
}
#endif

正如你所看到的,我非常渴望发布几乎整个项目,只是为了得到帮助! 这意味着我现在对C ++非常生气。 正如您所看到的,我是一名新手程序员,但我认为这对我来说是中等难度的 制作一个简单的RPG游戏,使用单独的HPP文件,而不是像以前那样在main.cpp中放置所有代码。

在此先感谢,我希望这不是太麻烦,至少不是专业程序员!

也许这有助于澄清: 我使用了一个名为PenguinProgrammer的网站:http://www.penguinprogrammer.co.uk/rpg-tutorial-2/battles/

你可以看到这个家伙使用了&#34; battle.hpp&#34;并做了类似的事情:

#include "dialogue.hpp"
Dialogue dialogue;

而且我不明白这对HIM有何影响,而不是对我有用。 我没有测试他的代码,我不是一个优秀的程序员,但在我的世界里,这似乎是 真的很奇怪! 对此有何回答?

3 个答案:

答案 0 :(得分:2)

您尝试做的是创建一个循环引用,这在C ++中是不允许的。

标题保护应出现在每个标题文件中,而不是出现在源文件中,如:

#ifndef HEADER_NAME_MACRO
#define HEADER_NAME_MACRO

//Header contents...

#endif

要修复循环引用问题,您需要重新访问设计以消除循环引用。通常,您可以通过让一个或多个标题仅通过指针或引用引用其他标题并转发声明另一个类来执行此操作:

标题A:

#ifndef HEADER_A
#define HEADER_A
//Forward declaration, you've told the compiler you'll eventually define B.
class B;

class A {
public:
    B* b;
};

#endif

和标题B:

#ifndef HEADER_B
#define HEADER_B

#include <A.hpp>

class B {
public:
    A a;
};

原因是C ++编译器需要知道在定义时定义的所有内容的大小。如果你有一个循环引用,编译器不知道你定义的那个的大小。

您在链接时也会遇到头文件中定义的非成员函数的问题。要解决此问题,您需要将它们放在源文件中或声明它们inline以绕过one definition rule

您似乎误解了人们通常如何在C ++中组织代码。标题应包含声明,您的源文件应包含 definitions 。见this c++-faq question about the difference

答案 1 :(得分:1)

您无需在任何.cpp文件中添加包含保护,您只应在头文件中使用包含保护。我可以看到你在main.cpp文件中的许多地方添加了包含警戒。

包含防护应该添加到头文件的第一行,即使这些头文件也会被多次包含,你只能获得它的内容一次,因为其余的部分将在prepossessing后被删除。

答案 2 :(得分:1)

找不到forest(),因为您在Areas.hpp之前使用了已定义的包含警示

#ifndef MAINMENU_HPP
#define MAINMENU_HPP

// ...

#ifndef MAINMENU_HPP
#include "Areas.hpp"
Areas areas;
#endif

// ...

要解决循环依赖关系,通常需要在头文件中使用前向声明。

在您的情况下,将函数 definitions 移动到.cpp文件并在头文件中只留下声明就足够了。