为什么不调用函数的 derived-class 版本?
Why isn't the derived-class version of the function being called?
我正在尝试将来自同一基 class 的多个不同的派生 class 存储在指针向量中。尝试调用这些对象之一的函数会导致分段错误。我没有太多地使用继承,但我已经尝试了我能找到的每个版本,它们要么导致分段错误,要么只是调用基函数 class.
我是 C++ 的新手,之前没有发布过太多内容,所以如果我共享了太多代码、遗漏了任何重要内容或在任何其他方面(风格、效率等)搞砸了,请告诉我.).
编辑:getPlayer 函数不再尝试 return 随机或人类,而是 return 一个指示要创建哪种类型的玩家的整数。新代码仍然会在同一点导致段错误。 (排除了 getPlayer,因为它只是 return 一个 int 并且不再是问题的原因。)
这是我定义基础 class(玩家)和衍生 classes(人类和随机)的地方:
#include <string>
#include <iostream>
#include <limits>
#include <time.h>
#include "Othello.h"
using namespace std;
// Player interface to choose game moves
class Player {
public:
// Selects and returns a move
virtual int getMove(Othello &game) {
return 0;
}
};
// User-operated player
class Human: public Player {
public:
int getMove(Othello &game) {
int move = 0;
bool valid= false;
while (!valid) {
cout << "Select a move: " << endl;
cout << "-> ";
cin >> move;
if (cin.good()) { valid = true; }
else {
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(),'\n');
cout << "Invalid input. Try again.\n" << endl;
}
}
return move;
}
};
// Basic bot - selects a move at random
class Random: public Player {
public:
int getMove(Othello &game) {
srand(time(NULL));
return ( 1 + rand() % game.n_moves );
}
};
这是导致行 move = players[state-1]->getMove(game)
:
出现段错误的主要函数
int main() {
// Select players (human, AI, random, etc.)
// players[0] is left empty to keep the index consistent with the player id
vector<Player*> players(2);
int type;
for ( int i : {1, 2} ) {
type = getPlayer(i);
if (type == 1) { players.push_back( new Human() ); }
else if (type == 2) { players.push_back( new Random() ); }
}
// Load and start the game
Othello game = loadBoard();
int state = game.getState(1); // 1 or 2 for turn, or 0 for game over
// Continue making moves until the game ends
int move;
int legal;
while(state != 0) {
game.print();
legal = 0;
cout << "PLAYER " << game.turn << endl;
while (legal == 0) {
move = players[state-1]->getMove(game);
legal = game.doMove(move);
}
state = game.getState();
}
game.print();
game.score();
return 1;
}
vector<Player*> players(2);
声明一个包含两个元素的向量,这两个元素都将默认初始化为 nullptr
.
稍后,您又添加了两个元素,因此 players
有 4 个元素。
当 state
的值为 1
或 2
时,对 players[state-1]->getMove(game);
的调用将取消引用空指针,从而导致您的分段错误。
您可能希望将 players
定义为最初为空 (vector<Player*> players;
),并更新此定义之前行的注释。 (当前形式的评论似乎与您稍后访问玩家向量的方式毫无意义。)
我正在尝试将来自同一基 class 的多个不同的派生 class 存储在指针向量中。尝试调用这些对象之一的函数会导致分段错误。我没有太多地使用继承,但我已经尝试了我能找到的每个版本,它们要么导致分段错误,要么只是调用基函数 class.
我是 C++ 的新手,之前没有发布过太多内容,所以如果我共享了太多代码、遗漏了任何重要内容或在任何其他方面(风格、效率等)搞砸了,请告诉我.).
编辑:getPlayer 函数不再尝试 return 随机或人类,而是 return 一个指示要创建哪种类型的玩家的整数。新代码仍然会在同一点导致段错误。 (排除了 getPlayer,因为它只是 return 一个 int 并且不再是问题的原因。)
这是我定义基础 class(玩家)和衍生 classes(人类和随机)的地方:
#include <string>
#include <iostream>
#include <limits>
#include <time.h>
#include "Othello.h"
using namespace std;
// Player interface to choose game moves
class Player {
public:
// Selects and returns a move
virtual int getMove(Othello &game) {
return 0;
}
};
// User-operated player
class Human: public Player {
public:
int getMove(Othello &game) {
int move = 0;
bool valid= false;
while (!valid) {
cout << "Select a move: " << endl;
cout << "-> ";
cin >> move;
if (cin.good()) { valid = true; }
else {
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(),'\n');
cout << "Invalid input. Try again.\n" << endl;
}
}
return move;
}
};
// Basic bot - selects a move at random
class Random: public Player {
public:
int getMove(Othello &game) {
srand(time(NULL));
return ( 1 + rand() % game.n_moves );
}
};
这是导致行 move = players[state-1]->getMove(game)
:
int main() {
// Select players (human, AI, random, etc.)
// players[0] is left empty to keep the index consistent with the player id
vector<Player*> players(2);
int type;
for ( int i : {1, 2} ) {
type = getPlayer(i);
if (type == 1) { players.push_back( new Human() ); }
else if (type == 2) { players.push_back( new Random() ); }
}
// Load and start the game
Othello game = loadBoard();
int state = game.getState(1); // 1 or 2 for turn, or 0 for game over
// Continue making moves until the game ends
int move;
int legal;
while(state != 0) {
game.print();
legal = 0;
cout << "PLAYER " << game.turn << endl;
while (legal == 0) {
move = players[state-1]->getMove(game);
legal = game.doMove(move);
}
state = game.getState();
}
game.print();
game.score();
return 1;
}
vector<Player*> players(2);
声明一个包含两个元素的向量,这两个元素都将默认初始化为 nullptr
.
稍后,您又添加了两个元素,因此 players
有 4 个元素。
当 state
的值为 1
或 2
时,对 players[state-1]->getMove(game);
的调用将取消引用空指针,从而导致您的分段错误。
您可能希望将 players
定义为最初为空 (vector<Player*> players;
),并更新此定义之前行的注释。 (当前形式的评论似乎与您稍后访问玩家向量的方式毫无意义。)