0

i've been trying to study for my finals by practicing classes and inheritance, this is what I've come up with so far for inheritance and such however I'm unsure how to fix the error occuring below.

#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: ";
}    

However upon compilation I get the following errors:

220 `player' undeclared (first use this function) 

Unsure exactly how to fix it as I've only recently started using OO approach. The error has a comment next to it above and is in case 2 in the main.

Cheers guys.

user1446002
  • 3
  • 1
  • 2

4 Answers4

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

player is a local variable with automatic storage duration, its lifetime is tied to the scope of case 1. You'll have to declare player prior to the switch (choice) in order to use it in all cases.

LihO
  • 41,190
  • 11
  • 99
  • 167
0

There is no player variable in scope of that case you need to define a player variable before the whole switch clause if you want all of the cases to be able to access that information. Also you'll need to thus check if the variable is NULL or not or if object actually created yet before you call a method since it thus won't guarantee it's made necessarily.

By doing this, you bring the variable player into scope so that all cases can see it:

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

If you do

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

Then case 2 doesn't have hero player in scope (assume cases are like if/else clauses) in your code it's even more apparent because you have braces around your cases.

richardhsu
  • 878
  • 5
  • 13
  • Ok thank you. All of you guys explained it well, but I think this is the easiest to understand if someone comes across the same problem. I'll check this as the correct answer. – user1446002 Jun 09 '12 at 09:49
0

Yes, you can't create objects inside switch-case block and expect them to exist outside. It's a scope issue. You may either declare it outside switch-case, or use singleton pattern (if you have only one player).

Protheus
  • 3,068
  • 4
  • 17
  • 25
0

You've misplaced a curly bracket which is confusing things. You have no bracket at the end of your mainAttrChoice switch i.e. after the break in its default case. This means that your player variable is actually defined in scope of the default case of the mainAttrChoice switch. Incidentally it also means that the first case of your outer switch has no break. The indentation of the code is misleading.

The scope of that default case statement, and indeed any case statement in general, is the scope in which the switch is situated i.e. they all share the same scope. Despite this you cannot define a variable in one case and have it available in another. Why? Well each case statement simply defines a point within the switch's scope that you can jump to. If you can jump to it then you could skip the initialisation of variables in earlier cases. See this question for more details.

You want to access the same variable across case statements then it must be declared outside the switch. To declare a variable local to a case statement you need to create the scope using curly braces. It appears that you have got away with not using curly braces when you declared the hero player because its the last case statement in the switch (I'm guessing there because I don't have a compiler to hand right now).

Community
  • 1
  • 1
Troubadour
  • 13,334
  • 2
  • 38
  • 57