Инициализация вектора без использования конструктора по умолчанию

#c

#c

Вопрос:

Как я могу уменьшить количество строк следующего кода без использования конструктора по умолчанию?

 #include <vector>

enum Rank { DEUCE, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE };

enum Suit { HEART, DIAMOND, CLUB, SPADE };

struct Card {
    Card(Rank r, Suit s) : rank(r), suit(s) { }
    Card(const Cardamp; copy) : rank(copy.rank), suit(copy.suit) {}

    Rank rank;
    Suit suit;
};

const Card deckOfCards[52] = {
    Card(ACE, HEART),
    Card(DEUCE, HEART),
    Card(THREE, HEART),
    Card(FOUR, HEART),
    Card(FIVE, HEART),
    Card(SIX, HEART),
    Card(SEVEN, HEART),
    Card(EIGHT, HEART),
    Card(NINE, HEART),
    Card(TEN, HEART),
    Card(JACK, HEART),
    Card(QUEEN, HEART),
    Card(KING, HEART),
    Card(ACE, DIAMOND),
    Card(DEUCE, DIAMOND),
    Card(THREE, DIAMOND),
    Card(FOUR, DIAMOND),
    Card(FIVE, DIAMOND),
    Card(SIX, DIAMOND),
    Card(SEVEN, DIAMOND),
    Card(EIGHT, DIAMOND),
    Card(NINE, DIAMOND),
    Card(TEN, DIAMOND),
    Card(JACK, DIAMOND),
    Card(QUEEN, DIAMOND),
    Card(KING, DIAMOND),
    Card(ACE, CLUB),
    Card(DEUCE, CLUB),
    Card(THREE, CLUB),
    Card(FOUR, CLUB),
    Card(FIVE, CLUB),
    Card(SIX, CLUB),
    Card(SEVEN, CLUB),
    Card(EIGHT, CLUB),
    Card(NINE, CLUB),
    Card(TEN, CLUB),
    Card(JACK, CLUB),
    Card(QUEEN, CLUB),
    Card(KING, CLUB),
    Card(ACE, SPADE),
    Card(DEUCE, SPADE),
    Card(THREE, SPADE),
    Card(FOUR, SPADE),
    Card(FIVE, SPADE),
    Card(SIX, SPADE),
    Card(SEVEN, SPADE),
    Card(EIGHT, SPADE),
    Card(NINE, SPADE),
    Card(TEN, SPADE),
    Card(JACK, SPADE),
    Card(QUEEN, SPADE),
    Card(KING, SPADE)
};

class Deck {
public:
    Deck() : cards(deckOfCards, deckOfCards   52) {}
    ~Deck() {}

private:
    std::vector<Card> cards;
};
  

Комментарии:

1. Обратите внимание, что ваш конструктор копирования выполняет в точности то же самое, что и тот, который компилятор предоставил бы вам неявно. Если вы все-таки пишете конструктор копирования, обязательно напишите также оператор присваивания копирования и деструктор (всякий раз, когда вам нужна одна из этих трех функций, обычно вам нужны все три).

2. Уменьшить количество строк? В дополнение к избавлению от лишнего конструктора копирования (согласно комментарию Джеймса) вы также можете удалить все разрывы строк в своем коде, таким образом, получая в итоге одну строку! Или, точнее, двумя строками, поскольку #include требуется отдельная строка. Я не думаю, что вы можете сделать это меньше, чем это.

3. @AndreyT: Я смотрел, как ты взламываешь, быть избитым, да?

Ответ №1:

Вы можете использовать цикл и добавлять элементы в контейнер в теле конструктора:

 Deck() 
{
    for (int rank = (int)DEUCE; rank <= (int)ACE;   rank) 
    {
        for (int suit = (int)HEART; suit <= (int)SPADE;   suit)
        {
            cards.push_back(Card((Rank)rank, (Suit)suit));
        }
    }
}
  

Это можно было бы сделать более чистым и менее подверженным ошибкам, если бы у вас были sentinels для FIRST_ENUMERATOR и LAST_ENUMERATOR для каждого перечисления, но даже без этого это все равно лучше, чем вводить все комбинации вручную.

Комментарии:

1. Хорошим советом для предотвращения ненужного перераспределения памяти будет использование cards.reserve(52); перед этим циклом. И чтобы оставить порядок элементов прежним, вам следует изменить enum Rank { DEUCE, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE }; на enum Rank { ACE, DEUCE, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING };

2. Ненавижу приведение C. Лично я бы определил, Rankamp; operator (Rankamp;) что также будет полезно при тестировании в проливах.