我正在开发一个用C ++设计游戏的项目,当我尝试从玩家那里移动时,我的程序一直在崩溃。该程序允许用户为两个玩家中的每一个选择它是计算机玩家还是人类玩家。如果它是人类玩家,它会收集玩家的名字。
当程序启动时,我的主类创建一个游戏对象,运行 selectPlayers()功能,然后运行 play()功能。程序正在加载,向我询问每个玩家的人或计算机,为人类收集名称并显示棋盘(显示在play()函数中,然后它会弹出一个弹出消息的窗口
程序停止工作,windows正在寻找解决方案
在下面的代码中添加了评论,以显示问题所在。如果我把一个cout放在它打印的那条线之上,但是那条线之后没有打印......如果我在我的HumanPlayer类的makeMove方法的第一行放一个cout,它就不会打印出来,所以程序在进入方法之前崩溃了。
以下是我的游戏类的标题:
#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()
{
}
任何帮助都会很棒,谢谢你们。
答案 0 :(得分:2)
您需要更改所有代码:
HumanPlayer p(name, LIGHT);
HumanPlayer * player1 = &p;
到此:
player1 = new HumanPlayer (name, LIGHT);
在您的代码中,您创建了一个局部变量,您可以为其指定一些内容。类中的成员变量永远不会被初始化。
答案 1 :(得分:2)
崩溃正在发生,因为player1
是一个狂野指针(即它不包含合法值)。您似乎尝试为其分配值,但执行错误,如下所示:
HumanPlayer p(name, LIGHT);
HumanPlayer * player1 = &p;
这里有两个问题。首先,您声明的对象是局部变量,因此尝试存储指向它的指针是一个很大的错误。它超出范围并在几行内被销毁。其次,你在这里声明一个完全独立的player
指针,而不是使用属于该类成员的指针。结果是您将局部变量存储在本地指针中,因此您的程序以后无需使用。
相反,这些行应该在堆(或免费商店)上实例化播放器类的新实例。传统的C ++会像这样使用'new'运算符:
player1 = new HumanPlayer(name, LIGHT);
但是,如果您使用的是现代编译器,那么您应该使用智能指针。这意味着你的Game
类应该声明这样的指针:
std::shared_ptr<Player> player1;
分配给他们的代码应该像这样:
player1 = make_shared<HumanPlayer>(name, LIGHT);
显然,您还需要对player2
进行类似的更改。
答案 2 :(得分:0)
您永远不会在player1
中初始化player2
或Game.selectPlayers()
。而是创建{em>新的临时变量Human
或Random
Player
类型,在方法结束后超出范围。
答案 3 :(得分:0)
由于您没有初始化指针,因此您的班级中有未初始化的数据。将它们设置为NULL
或使用指针交换器(shared_ptr
,unique_ptr
)来管理它们,因为它们将为您进行初始化。
与C#或Java等语言不同,C ++不会将成员变量设置为默认值,除非它们有默认构造函数,而指针则没有!