这是使用抽象类数组(C++)的正确方法吗?
忽略我使用原始指针/数组的事实。
我正在用 C++ 制作一个纸牌游戏,它有一个由其他类扩展的 Player
抽象类。我需要创建一个指向这些派生类的指针数组。这可行,但是有更好的方法吗?
class Player{
public:
Player();
Player(const Player&);
Player & operator=(const Player &);
virtual void sort() = 0;
virtual Card play(Pile*) = 0;
void confirmPlay();
void giveHand(Hand&);
void giveCard(Card);
bool hasCards();
void won();
void resetWins();
int getWins();
virtual ~Player();
protected:
int cardsLeft;
Hand hand;
int cardPlayed;
int wins;
private:
};
class DumbPlayer : public Player
{
public:
DumbPlayer();
Card play(Pile*);
void sort();
virtual ~DumbPlayer();
DumbPlayer & operator=(const DumbPlayer &);
DumbPlayer(const DumbPlayer&);
protected:
private:
};
class Game{
public:
Game(int, Player**&);
void playX(int);
void playOne();
virtual ~Game();
protected:
private:
bool done();
Game & operator=(const Game &);
Game(const Game&);
Pile * piles;
Deck deck;
int playerCount;
Player ** players;
};
//implementation not shown to save space, tell me if you would like to see anything.
//I think that all of the other class/function names should be good enough to not show.
Game::Game(const int pplayerCount, Player**& pplayers) :
piles(new Pile[4]),
playerCount(pplayerCount),
deck(),
players(new Player*[playerCount]){
for(int i = 0; i < 4; i++){
piles[i].setSuit(i);
}
for(int i = 0; i < playerCount; i++){
players[i] = pplayers[i];
}
}
void Game::playOne(){
deck.shuffle(); //shuffle deck
for(int i = 0; i < 4; i++){
piles[i].reset(); //reset piles
}
Hand hands[playerCount]; //create hands
Hand leftovers;
deck.dealAll(playerCount, hands, leftovers); //deal the deck
int cardsLeftover = leftovers.getSize(); //there are leftover cards,
//52/3 has a remainder
for(int playerIdx = 0; playerIdx < playerCount; playerIdx++){
(*players[playerIdx]).giveHand(hands[playerIdx]); //this is what
//i am unsure about.
(*players[playerIdx]).sort();
}
int winner = -1;
while(!done()){
for(int playerIdx = 0; playerIdx < playerCount; playerIdx++){
Card play = (*players[playerIdx]).play(piles);
if(piles[play.getSuit()].canPut(play)){
(*players[playerIdx]).confirmPlay();
piles[play.getSuit()].put(play);
if(!(*players[playerIdx]).hasCards()){
winner = playerIdx;
break;
}
} else {
if(cardsLeftover > 0){
(*players[playerIdx]).giveCard(leftovers.popCard(--cardsLeftover));
}
}
}
if(winner != -1){
(*players[winner]).won();
break;
}
}
}
我知道(对于这个网站)有大量代码...我不确定游戏构造函数/类以及包括 (*players[i]).x()
的行
Ignore the fact that I using raw pointers/arrays.
I am making a card game in C++ that has a Player
abstract class that is extended by other classes. I need to make an array of pointers to these derived classes. This works, but is there a better way?
class Player{
public:
Player();
Player(const Player&);
Player & operator=(const Player &);
virtual void sort() = 0;
virtual Card play(Pile*) = 0;
void confirmPlay();
void giveHand(Hand&);
void giveCard(Card);
bool hasCards();
void won();
void resetWins();
int getWins();
virtual ~Player();
protected:
int cardsLeft;
Hand hand;
int cardPlayed;
int wins;
private:
};
class DumbPlayer : public Player
{
public:
DumbPlayer();
Card play(Pile*);
void sort();
virtual ~DumbPlayer();
DumbPlayer & operator=(const DumbPlayer &);
DumbPlayer(const DumbPlayer&);
protected:
private:
};
class Game{
public:
Game(int, Player**&);
void playX(int);
void playOne();
virtual ~Game();
protected:
private:
bool done();
Game & operator=(const Game &);
Game(const Game&);
Pile * piles;
Deck deck;
int playerCount;
Player ** players;
};
//implementation not shown to save space, tell me if you would like to see anything.
//I think that all of the other class/function names should be good enough to not show.
Game::Game(const int pplayerCount, Player**& pplayers) :
piles(new Pile[4]),
playerCount(pplayerCount),
deck(),
players(new Player*[playerCount]){
for(int i = 0; i < 4; i++){
piles[i].setSuit(i);
}
for(int i = 0; i < playerCount; i++){
players[i] = pplayers[i];
}
}
void Game::playOne(){
deck.shuffle(); //shuffle deck
for(int i = 0; i < 4; i++){
piles[i].reset(); //reset piles
}
Hand hands[playerCount]; //create hands
Hand leftovers;
deck.dealAll(playerCount, hands, leftovers); //deal the deck
int cardsLeftover = leftovers.getSize(); //there are leftover cards,
//52/3 has a remainder
for(int playerIdx = 0; playerIdx < playerCount; playerIdx++){
(*players[playerIdx]).giveHand(hands[playerIdx]); //this is what
//i am unsure about.
(*players[playerIdx]).sort();
}
int winner = -1;
while(!done()){
for(int playerIdx = 0; playerIdx < playerCount; playerIdx++){
Card play = (*players[playerIdx]).play(piles);
if(piles[play.getSuit()].canPut(play)){
(*players[playerIdx]).confirmPlay();
piles[play.getSuit()].put(play);
if(!(*players[playerIdx]).hasCards()){
winner = playerIdx;
break;
}
} else {
if(cardsLeftover > 0){
(*players[playerIdx]).giveCard(leftovers.popCard(--cardsLeftover));
}
}
}
if(winner != -1){
(*players[winner]).won();
break;
}
}
}
I know that it is a ton of code (for this site)... i am unsure about the game constructor/class and the lines including (*players[i]).x()
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如今,指针数组被拼写为:
这完全符合资源获取即初始化 (RAII) 习惯用法 确保在遇到异常和不可预见的代码路径时正确调用析构函数并回收内存。
Nowadays, an array of pointers is spelled:
This takes full of the Resource Acquisition Is Initialization (RAII) idiom to ensure destructors are called properly and memory is reclaimed in the face of exceptions and unforeseen code paths.
使用 std::vector、列表、地图等。
Use std::vector, list, map etc.