0

我一直在尝试通过练习类和继承来学习我的期末考试,这是我迄今为止为继承提出的想法,但是我不确定如何解决下面发生的错误。

#include<iostream>
#include<iomanip>
#include<cmath>
#include<string.h>
using namespace std;


//BASE CLASS DEFINITION

class hero
{     
 protected:
            string name;
            string mainAttr;
            int xp;
            double hp;
            double mana;
            double armour;
            int range;
            double attkDmg;
            bool attkType;
  public:
         void dumpData();
         void getName();
         void getMainAttr();
         void getAttkData();
         void setAttkData(string);
         void setBasics(string, string, double, double, double);
         void levelUp();
};

//CLASS FUNCTIONS

void hero::dumpData()
{
 cout << "Name: " << name << endl;
 cout << "Main Attribute: " << mainAttr << endl;
 cout << "XP: " << xp << endl;
 cout << "HP: " << hp << endl;
 cout << "Mana: " << mana << endl;
 cout << "Armour: " << armour << endl;
 cout << "Attack Range: " << range << endl;
 cout << "Attack Damage: " << attkDmg << endl;
 cout << "Attack Type: " << attkType  << endl << endl;
}

void hero::getName()
{
     cout << "Name: " << name << endl;
}

void hero::getMainAttr()
{
     cout << "Main Attribute: " << mainAttr << endl;
}

void hero::getAttkData()
{
     cout << "Attack Range: " << range << endl;
     cout << "Attack Damage: " << attkDmg << endl;
     cout << "Attack Type: " << attkType  << endl;
}

void hero::setAttkData(string attr)
{
     int choice = 0;

     if (attr == "Strength")
 {
          choice = 1;
 }
 if (attr == "Agility")
 {
          choice = 2;
 }
 if (attr == "Intelligence")
 {
          choice = 3;
 }

 switch (choice)
 {
        case 1:
             range = 128;
             attkDmg = 80.0;
             attkType = 0;
             break;

        case 2:
             range = 350;
             attkDmg = 60.0;
             attkType = 0;
             break;

        case 3:
             range = 600;
             attkDmg = 35.0;
             attkType = 1;
             break;

        default:
                break;
 }
}

void hero::setBasics(string heroName, string attribute, double health, double mp, double armourVal)
{
     name = heroName;
     mainAttr = attribute;
     hp = health;
     mana = mp;
     armour = armourVal;
}

void hero::levelUp()
{
     xp = 0;
     hp = hp + (hp * 0.1);
     mana = mana + (mana * 0.1);
     armour = armour + ((armour*0.1) + 1);
     attkDmg = attkDmg + (attkDmg * 0.05);
}

//INHERITED CLASS DEFINITION

class neutHero : protected hero
{
      protected:
            string drops;
            int xpGain;
      public:
         int giveXP(int);
         void dropItems();
};

//INHERITED CLASS FUNCTIONS

int neutHero::giveXP(int exp)
{
    xp += exp;
}

void neutHero::dropItems()
{
     cout << name << " has dropped the following items: " << endl;
     cout << drops << endl;
}

/*
  END OF OO!
*/

//FUNCTION PROTOTYPES
    void dispMenu();


int main()
{
    int exit=0, choice=0, mainAttrChoice=0, heroCreated=0;
    double health, mp, armourVal;
    string heroName, attribute;

    do
    {
      dispMenu();
      cin >> choice;

      switch (choice)
      {
      case 1:
           system("cls");
           cout << "Please enter your hero name: ";
           cin >> heroName;
           cout << "\nPlease enter your primary attribute\n";
           cout << "1. Strength\n" << "2. Agility\n" << "3. Intelligence\n";
           cin >> mainAttrChoice;
           switch (mainAttrChoice)
           {
              case 1:
                   attribute = "Strength";
                   health = 750;
                   mp = 150;
                   armourVal = 2;
                   break;

              case 2:
                   attribute = "Agility";
                   health = 550;
                   mp = 200;
                   armourVal = 6;
                   break;

              case 3:
                   attribute = "Intelligence";
                   health = 450;
                   mp = 450;
                   armourVal = 1;
                   break;
              default:
                   cout << "Choice invalid, please try again.";
                   exit = 1;
                   break;


       hero player;
       player.setBasics(heroName, attribute, health, mp, armourVal);
       player.setAttkData(attribute);
       heroCreated=1;
       system("cls");
       cout << "Your hero has been created!\n\n";
       player.dumpData();
       system("pause");

       break;

      } 
  case 2:
       system("cls");
       if (heroCreated == 1)
       {
          cout << "Your hero has been detailed below.\n\n";
          **player.dumpData(); //ERROR OCCURS HERE !**
          system("pause");
       }
       else
       {
           cout << 
           "You have not created a hero please exit this prompt "
           "and press 1 on the menu to create a hero.";
       }
       break;

  case 3:
       system("cls");
       cout << "Still Under Development";
       system("pause");
       break;

  case 4:
       system("cls");
       exit = 1;
       break;

  default:
       cout << "Your command has not been recognised, please try again.\n";
       system("pause");
       break;
  }
}
while (exit != 1);

system("pause");
return 0;

}

void dispMenu()
{
     system("cls");
     cout <<
     "1. Create New Hero\n"
     "2. View Current Hero\n"
     "3. Fight Stuff\n"     
     "4. Exit\n\n"     
     "Enter your choice: ";
}    

但是在编译时我得到以下错误:

220 `player' undeclared (first use this function) 

不确定如何修复它,因为我最近才开始使用 OO 方法。该错误在上面有一个注释,主要是案例 2。

干杯,伙计们。

4

4 回答 4

1
switch (choice)
{
    case 1:
    {
        hero player;
        ...
    }
    case 2:
        player.dumpData(); //ERROR OCCURS HERE !

player是一个具有自动存储持续时间的局部变量,它的生命周期与case 1. 您必须在player之前声明switch (choice)才能在所有情况下使用它。

于 2012-06-09T09:43:27.577 回答
0

如果您希望所有案例都能够访问该信息,则该案例的范围内没有player变量,您需要在整个 switch 子句之前定义一个变量。player因此,您还需要在调用方法之前检查变量是否为 NULL 或对象是否实际创建,因为它因此不能保证它是必要的。

通过这样做,您将变量player带入范围,以便所有案例都可以看到它:

hero player;
switch () {
    case 1:
        player.dostuff();
        break;
    case 2:
        player.domorestuff();
        break;
}

如果你这样做

switch () {
    case 1:
        player.dostuff();
        hero player;
        break;
    case 2:
        player.domorestuff();
        break;
}

那么案例 2 在您的代码中没有英雄播放器(假设案例类似于 if/else 子句),因为您的案例周围有大括号,所以更加明显。

于 2012-06-09T09:41:18.530 回答
0

是的,您不能在 switch-case 块内创建对象并期望它们存在于外部。这是一个范围问题。你可以在 switch-case 之外声明它,或者使用单例模式(如果你只有一个玩家)。

于 2012-06-09T09:42:23.597 回答
0

您放错了一个大括号,这使事情变得混乱。您的mainAttrChoice开关末端没有支架,即在其default外壳中断之后。这意味着您的player变量实际上是default在 switch 的 case范围内定义的mainAttrChoice。顺便说一句,这也意味着您的外部开关的第一个案例没有break. 代码的缩进具有误导性。

该默认 case 语句的范围,实际上是任何一般的 case 语句,都是 switch 所在的范围,即它们都共享相同的范围。尽管如此,您不能在一种情况下定义变量并使其在另一种情况下可用。为什么?好吧,每个 case 语句都只是定义了 switch 范围内的一个点,您可以跳转到该点。如果您可以跳转到它,那么您可以在早期情况下跳过变量的初始化。有关更多详细信息,请参阅此问题

如果您想跨 case 语句访问相同的变量,那么它必须在 switch 之外声明。要声明 case 语句的局部变量,您需要使用花括号创建范围。看来您在声明时没有使用花括号,hero player因为它是 switch 中的最后一个 case 语句(我猜是因为我现在手头没有编译器)。

于 2012-06-09T09:54:43.373 回答