2011-12-09 53 views
0

忽略我使用原始指針/數組的事實。

我正在用C++製作一個卡片遊戲,其中有一個由其他類擴展的Player抽象類。我需要爲這些派生類創建一個指針數組。這有效,但有沒有更好的方法?這是使用抽象類(C++)數組的正確方法嗎?

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()

+0

不要使用原始指針。不要使用原始數組。請使用標準庫元素。 –

+1

我對你的問題仍然不清楚,但是如果你只是對'(* players [i] .x())'語法感到不滿,你可以通過說'players [i] - > x()'代替。除此之外,你對忽略使用原始指針和數組這一事實的評論有點誤導了恕我直言,你問我們你可以做些什麼來改進你的代碼,而智能指針和向量是你的重要組成部分可以做得更強大。 –

回答

4

如今,指針數組的拼寫:

std::vector<boost::shared_ptr<Player> > players; 

這需要充分的Resource Acquisition Is Initialization (RAII) idiom的,以確保析構函數被正確調用和存儲器是RECL旨在面對例外和無法預料的代碼路徑。

+3

甚至boost :: ptr_vector Alek86

+1

更喜歡boost :: ptr_vector 它不僅管理指針。但它將其元素公開爲對象的引用。因此,將它與標準算法一起使用要簡單得多。 –

+0

我總是忘記ptr_containers。感謝您的提醒! –

1

使用std ::矢量線條,列表,映射等

相關問題