2010-03-20 3 views
3

Я программирую простую текстовую RPG, используя оператор switch для игрового цикла. Программа работает нормально до тех пор, пока я не попытаюсь добавить другой оператор case, и в этот момент он дает мне следующие три ошибки: «перейти к метке case» (ошибка возникает в строке вновь добавленного случая) и две «крестики инициализации», ClassName * objectName '"(ошибки возникают, когда новые объекты создаются в случае 2). Я вставлю важный код, если кому-то нужно больше, пожалуйста, дайте мне знать.Ошибка оператора C++ Switch

int main(void) 
{ 
    // add weapons to array 
    Weapon *weaponList[12]; 
    // Rusty Sword 
    weaponList[0] = new Weapon(0,0,0); 
    weaponList[0]->SetAll(0,2,3); 
    // Bronze Sword 
    weaponList[1] = new Weapon(0,0,0); 
    weaponList[1]->SetAll(1,5,10); 
    // Bronze Battle Axe 
    weaponList[2] = new Weapon(0,0,0); 
    weaponList[2]->SetAll(2,15,30); 
    // Iron Sword 
    weaponList[3] = new Weapon(0,0,0); 
    weaponList[3]->SetAll(3,25,70); 

    // add armor to array 
    Armor *armorList[12]; 
    // Worn Platemail 
    armorList[0] = new Armor(0,0,0); 
    armorList[0]->SetAll(0,2,3); 
    // Bronze Chainmail 
    armorList[1] = new Armor(0,0,0); 
    armorList[1]->SetAll(1,5,8); 
    // Bronze Platemail 
    armorList[2] = new Armor(0,0,0); 
    armorList[2]->SetAll(2,7,20); 
    // Iron Chainmail 
    armorList[3] = new Armor(0,0,0); 
    armorList[3]->SetAll(3,15,60); 

     while(gamestate != 8) 
     { 
      switch(gamestate) 
      { 
       case 0: 
       cout << " /| Welcome!\n" 
        << " || \n" 
        << " || \n" 
        << " || \n" 
        << "_||_ \n" 
        << " 88 \n" 
        << " 88 Name: "; 
       cin >> heroName; 
       gamestate = GAME_STATE_MENU; 
       break; 

      case 1: 
       cout << "\n" 
        << "'/stats' will show you your stats\n" 
        << "'/shop' will let you visit the weapon shop\n" 
        << "secret commands: /setweapon # /setarmor # /setheroexp #\n" 
        << "\n"; 

       cout << "Command: "; 
       cin >> command; 

       if (strcmp(command, "/stats") == 0) 
       { 
        gamestate = 2; 
        break; 
       } 

       else if (strcmp(command, "/shop") == 0) 
       { 
        gamestate = 3; 
        break; 
       } 

       else if (strcmp(command, "/fight") == 0) 
       { 
        gamestate = 4; 
        break; 
       } 

       else if (strcmp(command, "/setweapon") == 0) 
       { 
        cin >> testNum; 
        heroWeapon = testNum; 
        break; 
       } 

       else if (strcmp(command, "/setarmor") == 0) 
       { 
        cin >> testNum; 
        heroArmor = testNum; 
        break; 
       } 

       else if (strcmp(command, "/setheroexp") == 0) 
       { 
        cin >> testNum; 
        heroExp = testNum; 
        LevelUp(); 
        break; 
       } 

       else if (strcmp(command, "/exit") == 0) 
       { 
        gamestate = 8; 
        break; 
       } 

       else 
       { 
        cout << "Please enter a valid command.\n"; 
        gamestate = 2; 
        break; 
       } 

      case 2: 
       Weapon *wCurrent = weaponList[heroWeapon]; 
       Armor *aCurrent = armorList[heroArmor]; 
       heroWeaponPower = wCurrent->GetWeaponAttack(); 
       heroArmorDefense = aCurrent->GetArmorDefense(); 
       heroPowerDefault = ((heroLevel - 1) * 10) + 10; 
       heroPower = heroPowerDefault + (heroStrength * 2) + heroWeaponPower; 
       heroDefenseDefault = ((heroLevel - 1) * 2) + 5; 
       heroDefense = heroDefenseDefault + (heroAgility/5) + heroArmorDefense; 
       heroHealthDefault = (heroLevel * 5) + 20; 
       heroHealth = heroHealthDefault + (heroStamina * 10); 
       cout << "\nS T A T S\nName: " 
        << heroName 
        << "\nLevel: " 
        << heroLevel 
        << "\nExp: " 
        << heroExp << "/" << expForLevel[heroLevel] 
        << "\nGold: " 
        << heroGold 
        << "\nHealth: " 
        << heroHealth 
        << "\nPower: " 
        << heroPower 
        << "\nDefense: " 
        << heroDefense 
        << "\nWeapon: " 
        << weaponNameList[heroWeapon] 
        << "\nArmor: " 
        << armorNameList[heroArmor] 
        << "\n\n"; 
       system("PAUSE"); 
       gamestate = 2; 
       break; 

      case 3: 
       break; 
      } 
     } 

     return 0; 
    } 
+3

Возможно, это зависит от кода, который вы закомментировали. –

+1

Да, ваш код с комментариями, вероятно, является виновником. – Jaxidian

+1

Зачем нужен перерыв для каждой ветви if/else, когда у вас может быть один перерыв для всего этого случая? – Steve314

ответ

9

По звукам этого, у вас есть:

case 2: 
    Type somevar = ...; 
    ... 
    break; 

case 3: 

Чтобы добраться до случая 3, компилятор генерирует скачок после инициализации somevar.

Чтобы исправить, используйте скобки, чтобы создать блок, окружающий объявление переменной:

case 2: 
    { 
    Type somevar = ...; 
    ... 
    } 
    break; 
6

декларации Wrap в кадре стека ... э-э ... локальная область ... :)

switch(gamestate) 
{ 
    case 0: 
    { 
     Apple a; 
     a.DoSomething(); 
    } 
    break; 

    case 1: /* etc. */ break; 
    case 2: /* etc. */ break; 
} 

... или переместить их за пределы коммутатора:

Apple A; 
switch(gamestate) 
{ 
    case 0: a.DoSomething(); break; 
+0

Это не кадр стека, а область блока. Это правильный способ решить проблему. –

+0

Правда, мое плохое. Аналогично работает с точки зрения срока жизни объекта. http://msdn.microsoft.com/en-us/library/b7kfh662%28VS.80%29.aspx – 2010-03-20 03:25:20

+0

В этом была проблема! Благодаря :) – 2010-03-20 03:26:17

3

Рассмотрим следующее:

switch (x) 
{ 
    case 0: 
     int i = 0; 
    case 1: 
     i = 5; 
} 

Что делать, если x равен 1? Затем мы пропустим за инициализацией i и только начнем использовать его. Это то, что вы получаете: case 3 имеет доступ к переменным от case 2, но если вы их используете, вы начали использовать их, не выполнив свою инициализацию.

Обычным решением является введение сферы:

switch (x) 
{ 
    case 0: 
    { 
     int i = 0; 
    } 
    case 1: 
    { 
     i = 5; // not possible, no i in this scope 
    } 
} 
3

редактировать

Теперь, когда мы видим больше кода, проблема очевидна, это

 case 2: 
      Weapon *wCurrent = weaponList[heroWeapon]; 
      Armor *aCurrent = armorList[heroArmor]; 

объявляет две переменные, так что вы можете после того, как вы завернете корпус корпуса 2 в {}

происхождение аль ответ ниже


Область действия переменных, объявленных в случае являются фигурные скобки, внутри которых выключатель, если не добавить дополнительный набор скобок. так что это работает.

switch(gamestate) 
    { 
     case 0: 
      foo a; 
      break; 
    } 

но это позволяет случаю 1 пропустить инициализацию, но все же ссылаться на нее, поэтому она генерирует ошибку.

switch(gamestate) 
    { 
     case 0: 
      foo a; 
      break; 

     case 1: 
      break; 
    } 

Так что вам нужно сделать это вместо этого, теперь область действия a ограничена случаем 0.

switch(gamestate) 
    { 
     case 0: 
      { 
      foo a; 
      } 
      break; 

     case 1: 
      break; 
    } 

Incidently, при редактировании кода, чтобы оставить из несущественного материала, вы также удалили код, который вызвал проблему. ;)

Смежные вопросы