2013-11-28 3 views
1

Я работаю над проектом по разработке игры на C++, и моя программа продолжает сбой, когда я пытаюсь получить переход от игрока. Программа позволяет пользователю выбирать для каждого из двух игроков, если это будет компьютерный плеер или человек. Если это игрок-человек, он собирает имя для игрока.Сбой программы C++ после использования -> Оператор

При запуске программы, мой основной класс создает объект игры, запускает selectPlayers() функции, а затем запускает воспроизведения() функции. Программа загружается, спрашивает меня о человеке или компьютере для каждого игрока, собирая имя для людей и отображая плату (которая отображается в функции play(), а затем она вылетает с окном, которое появляется с сообщением

программа перестала работать, окно ищет решение

Добавлено комментарий в коде ниже, чтобы показать, где проблема. Если я ставлю COUT выше этой линии, она печатает, но ничего после этой строки принтов ... И если я положил cout на самую первую строку метода makeMove в моем классе HumanPlayer, он не будет напечатан, поэтому программа будет сбой, прежде чем попасть в метод.

Вот заголовок для моего игрового класса:

#include "Board.h" 
#include "Player.h" 
#ifndef GAME_H_INCLUDED 
#define GAME_H_INCLUDED 
class Game 
{ 
    Board b; 
    int turn; 
    bool winner; 
    Player* player1; 
    Player* player2; 
public: 
    Game(); 
    ~Game(); 
    void selectPlayers(); 
    Player* nextPlayer() const; 
    void play(); 
    void announceWinner(); 
}; 

#endif // GAME_H_INCLUDED 

И сам класс:

#include "Game.h" 
#include "HumanPlayer.h" 
#include "RandomPlayer.h" 
#include <iostream> 
Game::Game() 
{ 
    b.reset(); 
    turn = 1; 
    winner = false; 
} 
Game::~Game() 
{ 

} 
void Game::selectPlayers() 
{ 
    int x = 0; 
    std::string type; 
    std::string name; 
    std::cout << "Enter type for Player 1 (Human/Computer): "; 
    std::cin >> type; 
    while(x == 0) 
    { 
     if(type.compare("Human") == 0) 
     { 
      x = 1; 
      std::cout << "Enter name for Player 1: "; 
      std::cin >> name; 
      HumanPlayer p(name, LIGHT); 
      HumanPlayer * player1 = &p; 
     } 
     else if(type.compare("Computer") == 0) 
     { 
      x = 1; 
      RandomPlayer p(1, LIGHT); 
      RandomPlayer * player1 = &p; 
     } 
     else 
     { 
      std::cout << "Please enter Human or Computer for Player 1: "; 
      std::cin >> type; 
     } 
    } 
    std::cout << "Enter type for Player 2 (Human/Computer): "; 
    std::cin >> type; 
    x = 0; 
    while(x == 0) 
    { 
     if(type.compare("Human") == 0) 
     { 
      x = 1; 
      std::cout << "Enter name for Player 2: "; 
      std::cin >> name; 
      HumanPlayer p(name, DARK); 
      HumanPlayer * player2 = &p; 
     } 
     else if(type.compare("Computer") == 0) 
     { 
      x = 1; 
      RandomPlayer p(2, DARK); 
      RandomPlayer * player2 = &p; 
     } 
     else 
     { 
      std::cout << "Please enter Human or Computer for Player 2: "; 
      std::cin >> type; 
     } 
    } 
} 
Player* Game::nextPlayer() const 
{ 

} 
void Game::play() 
{ 
    while(winner == false) 
    { 
     b.display(); 
     if(turn%2 == 1) 
     { 
      player1->makeMove(b); //PROGRAM CRASHES HERE 
      ++turn; 
     } 
     else 
     { 
      player2->makeMove(b); 
      ++turn; 
     } 
    } 
} 
void Game::announceWinner() 
{ 

} 

Любая помощь будет удивительным, спасибо, ребята.

ответ

2

вам необходимо изменить весь код, как это:

 HumanPlayer p(name, LIGHT); 
     HumanPlayer * player1 = &p; 

к этому:

 player1 = new HumanPlayer (name, LIGHT); 

В своем коде вы создали локальную переменную, присвоенным что-то к нему. Член-переменная в классе никогда не инициализируется.

+1

Не забудьте удалить их в деструкторе! Или просто используйте интеллектуальные указатели, такие как 'std :: unique_ptr' или' std :: shared_ptr'. –

0

Вы никогда не инициализируете player1 или player2 в Game.selectPlayers(). Вместо этого вы создаете новую переменную либо Human, либо RandomPlayer тип, который выходит за рамки после завершения метода.

0

Вы получили неинициализированные данные в своем классе, поскольку вы не инициализируете указатели. Либо установите их на NULL, либо используйте указатель swapper (shared_ptr, unique_ptr), чтобы управлять ими, поскольку они позаботятся об инициализации для вас.

В отличие от языков, таких как C# или Java, C++ не устанавливает ваши переменные-члены в значения по умолчанию, если у них нет конструктора по умолчанию, а указатели нет!

2

Аварийное происшествие происходит потому, что player1 является диким указателем (то есть, он не содержит законного значения). Похоже, вы пытаетесь присвоить ему значение, но делает это неправильно, а именно:

HumanPlayer p(name, LIGHT); 
HumanPlayer * player1 = &p; 

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

Вместо этого эти строки должны создавать экземпляр класса игрока в куче (или бесплатном хранилище). Обычный C++ будет использовать «новый» оператор так:

player1 = new HumanPlayer(name, LIGHT); 

Однако, если вы используете современный компилятор, вы действительно должны использовать смарт-указатели вместо этого. Это означает, что ваш Game класс должен объявлять указатели как это:

std::shared_ptr<Player> player1; 

И код, чтобы назначить им должно быть сделано так:

player1 = make_shared<HumanPlayer>(name, LIGHT); 

Очевидно, что вам нужно сделать аналогичные изменения для player2 также.

+0

Я думаю, что 'std :: unique_ptr' должно быть достаточно для его использования. –

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