Как я могу вернуть экземпляр класса, используя шаблон Builder в C ++? - PullRequest
0 голосов
/ 13 марта 2020

Я пытаюсь создать простую карточную игру. Цель состоит в том, чтобы иметь более устойчивый gr asp с C ++ (у меня есть опыт только с Java до сих пор). В частности, я изо всех сил пытаюсь полностью понять указатели, несмотря на то, что я читал и смотрел бесчисленные материалы по всей сети.

#include "../header_files/Card.h"

class Card {
public:
    void setCardName(const string& name){
        card_name = name;
    }
    void setCardPower(const int& pow){
        card_power = pow;
    }
    void setLuck(const int& luck){
        card_luck = luck;
    }

    void printCardDetails() {
        std::cout << "\nCard: " << card_name
                << "Luck:  "<< card_luck <<
                "Power: " << card_power <<"\n" << std::endl;
    }

private:
    string card_name;
    int card_power;
    int card_luck;
};

class CardBuilder{
public: virtual ~CardBuilder() {};

    Card* getCard(){
        return card.release();
    }
    void createNewCard(){
        card = make_unique<Card>();
    }

    virtual void setCardName() = 0;
    virtual void setCardPower() = 0;
    virtual void setCardLuck() = 0;

protected:
    unique_ptr<Card> card;
};


class CardType1Builder : public CardBuilder {
public:
    virtual ~CardType1Builder() {};

    virtual void setCardName(){
        card->setCardName("Card Type 1");
    }
    virtual void setCardPower(){
        card->setCardPower(1+ (rand() %10));
    }
    virtual void setCardLuck(){
        card->setLuck(1+ (rand() %5));
    }
};

class CardType2Builder : public CardBuilder {
public:
    virtual ~CardType2Builder() {};

    virtual void setCardName(){
        card->setCardName("Card Type 2");  //36
    }
    virtual void setCardPower(){
        card->setCardPower(1+ (rand() %10));
    }
    virtual void setCardLuck(){
        card->setLuck(1+ (rand() %5));
    }
};

class CardGenerator {
public:
    void printCard() {
        cardBuilder->getCard()->printCardDetails();
    }
    void constructCard(CardBuilder* cb){
        cardBuilder = cb;
        cardBuilder->createNewCard();
        cardBuilder->setCardName();
        cardBuilder->setCardPower();
        cardBuilder->setCardLuck();
    }

private:
    CardBuilder* cardBuilder;
};

Теперь я хотел бы создать класс Deck с несколькими экземплярами классов построен по CardBuilder. В частности, я попробовал следующее:

class Deck {

private:
    CardGenerator cardGenerator;
    CardType1Builder cardType1Builder;
    CardType1Builder cardType2Builder;
    Card card1;
    Card card2;  

public:
void generateCards() {
    card1 = *cardGenerator.constructCard(&cardType1Builder); //trying to dereference the pointer
    cardGenerator.printCard();

    card1 cardGenerator.constructCard(&cardType2Builder);
    cardGenerator.printCard();


}
};

Но, к сожалению, не работает, я, вероятно, неправильно понял цель оператора *. Спасибо.

1 Ответ

0 голосов
/ 13 марта 2020

Вы не неправильно поняли оператор * (по крайней мере, я так не думаю).

Эта строка здесь не будет компилироваться

card1 = *cardGenerator.constructCard(&cardType1Builder); 

Это потому, что cardGenerator является автоматизированным c объектом, а не указателем. В C ++ объекты могут быть построены как автоматические c или динамические c объекты. Если у автоматических c объектов есть время жизни, управляемое их областью, динамические c объекты существуют до тех пор, пока они не будут удалены вручную (или ваши программы не прекратят выполняться), и к ним не будут обращаться через указатели. Просто удалите * из cardGenerator, и он должен скомпилироваться и нормально работать.

Примечание: int является базовым c типом в C ++, это означает, что вы должны передавать его по значению, а не по ссылке (тем более что в некоторых системах int на самом деле меньше, чем указатель (ссылка - это просто константный указатель))

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...