C ++:在交换机中调用类函数

时间:2012-06-09 09:38:25

标签: c++ class switch-statement instance

我一直在努力通过练习课程和继承来学习我的决赛,这是我迄今为止提出的继承,但是我不确定如何解决下面发生的错误。

#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 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

在这种情况下,如果您希望所有案例都能够访问该信息,则需要在整个switch子句之前定义player变量的范围内没有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子句),这更加明显,因为你的情况周围有大括号。

答案 2 :(得分:0)

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

答案 3 :(得分:0)

你错放了一个令人困惑的大括号。您的mainAttrChoice开关末尾没有括号,即default案例中断后。这意味着您的player变量实际上是在default转换的mainAttrChoice案例范围内定义的。顺便提一下,这也意味着外部交换机的第一种情况没有break。代码的缩进是误导性的。

该默认案例陈述的范围,实际上通常是任何案例陈述,是交换机所处的范围,即它们都共享相同的范围。尽管如此,您无法在一个案例中定义变量并在另一个案例中使用它。为什么?那么每个case语句只是定义了一个可以跳转到的开关范围内的一个点。如果你可以跳转到它,那么你可以跳过早期情况下变量的初始化。有关详细信息,请参阅this question

您希望跨case语句访问相同的变量,然后必须在switch之外声明它。要声明case语句的本地变量,您需要使用花括号创建范围。当你声明hero player时,你似乎没有使用花括号,因为它是交换机中的最后一个case语句(我猜是因为我没有编译器到现在手。)