2012-06-09 28 views
0

我一直在嘗試通過實踐類和繼承來學習我的決賽,這是我迄今爲止提出的繼承,但是我不確定如何修復發生在下面的錯誤。C++:調用交換機內的類功能

#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) 

不確定究竟如何解決它,因爲我一直在使用面向對象的方法只是最近纔開始。該錯誤在上面旁邊有一個註釋,並在主要情況下爲2。

乾杯傢伙。

+0

220是哪裏?通過評論突出顯示 –

回答

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子句)在代碼中更加明顯,因爲您的案例中有大括號。

+0

好的,謝謝。大家都解釋清楚了,但我認爲如果有人遇到同樣的問題,這是最容易理解的。我會檢查這是正確的答案。 – user1446002

0

是的,你不能在switch-case塊內創建對象,並期望它們存在於外部。 這是一個範圍問題。你可以在switch case外聲明它,或者使用單例模式(如果你只有一個播放器)。

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

player是具有自動存儲持續時間的局部變量,它的壽命是聯繫在一起的case 1範圍。您必須在switch (choice)之前聲明player才能在所有情況下使用它。

0

你錯過了一個令人困惑的事情的大括號。您的mainAttrChoice交換機末端沒有支架,即在其default案例中斷後。這意味着您的player變量實際上在mainAttrChoice交換機的default案例的範圍內定義。順便說一句,這也意味着你的外部開關的第一個情況沒有break。代碼的縮進具有誤導性。

該默認情況說明的範圍以及實際上一般情況下的任何情況說明都是該開關所處的範圍,即它們都具有相同的範圍。儘管如此,你不能在一種情況下定義一個變量,並在另一種情況下使用它。爲什麼?那麼每個案例陳述只是定義了一個可以跳轉到的開關範圍內的點。如果你可以跳到它,那麼你可以跳過早期情況下變量的初始化。有關更多詳細信息,請參閱this question

您想要跨越case語句訪問相同的變量,那麼它必須在交換機之外聲明。要爲case語句聲明局部變量,需要使用大括號來創建範圍。看起來,當你聲明heroplayer是因爲它在交換機中的最後一個case語句(我猜那裏是因爲我沒有編譯器現在處理)而沒有使用花括號。