Это правильный способ использовать массив абстрактных классов (C ++)? - PullRequest
0 голосов
/ 09 декабря 2011

Не обращайте внимания на тот факт, что я использую сырые указатели / массивы.

Я делаю карточную игру на 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()

Ответы [ 2 ]

4 голосов
/ 10 декабря 2011

В настоящее время пишется массив указателей:

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

Для этого требуется полная идиома Инициализация получения ресурсов (RAII) , чтобы гарантировать, что деструкторы вызываются должным образом и память восстанавливаетсяперед лицом исключений и непредвиденных путей кода.

1 голос
/ 09 декабря 2011

Используйте std :: vector, list, map и т. Д.

...