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

その場合の範囲に変数はありません。すべてのケースでその情報にアクセスできるようにする場合は、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句のようなものであると想定)。ケースを中かっこで囲んでいるため、さらに明確になります。

于 2012-06-09T09:41:18.530 に答える
0

はい、switch-caseブロック内にオブジェクトを作成して、それらが外部に存在することを期待することはできません。これはスコープの問題です。switch-caseの外側で宣言するか、シングルトンパターンを使用することができます(プレーヤーが1人だけの場合)。

于 2012-06-09T09:42:23.597 に答える
0

混乱を招く中括弧を置き忘れました。mainAttrChoiceスイッチの最後、つまりケースのブレークの後にブラケットがありませんdefault。これは、player変数が実際にはスイッチのdefaultケースのスコープで定義されていることを意味しますmainAttrChoice。ちなみに、外側のスイッチの最初のケースには がないことも意味しますbreak。コードのインデントは誤解を招きます。

そのデフォルトの case ステートメントのスコープ、および実際には一般的なすべての case ステートメントのスコープは、スイッチが配置されているスコープです。つまり、それらはすべて同じスコープを共有しています。それにもかかわらず、ある場合に変数を定義して別の場合に使用できるようにすることはできません。なんで?各 case ステートメントは、ジャンプできるスイッチのスコープ内のポイントを定義するだけです。それにジャンプできる場合は、以前のケースで変数の初期化をスキップできます。詳細については、この質問を参照してください。

case ステートメント間で同じ変数にアクセスしたい場合は、スイッチの外側で宣言する必要があります。case ステートメントに対してローカルな変数を宣言するには、中かっこを使用してスコープを作成する必要があります。switch の最後の case ステートメントであるため、を宣言したときに中括弧を使用しないで済んhero playerだようです (現在手元にコンパイラがないため、推測しています)。

于 2012-06-09T09:54:43.373 に答える