Оператор приращения перегрузки, циклы и крайние случаи - PullRequest
0 голосов
/ 07 октября 2010

У меня есть enum, который выглядит так:

enum Suit {Clubs, Diamonds, Hearts, Spades};

Я хочу перегрузить оператор приращения, чтобы я мог легко зациклить этих четырех парней.

Когда переменная - Клубы, Алмазы или Сердца, проблема не возникает. Это состояние Пики, которое доставляет мне небольшие неприятности.

Моим первым инстинктом было определить его так, чтобы, когда переменная была пиковой, приращение устанавливало ее равной трефам. Проблема в том, что это, кажется, делает невозможным цикл по 4 значениям в перечислении.

Если я сделаю что-то вроде

for(Suit i=Clubs;i<Spades;++i)
     {cout<<i<<endl;}

тогда мой вывод идет только в Hearts.

Если я сделаю

for(suit i=Clubs;i<=Spades;++i)
    {cout<<i<<endl;}

тогда мой вывод просто зацикливается навсегда!

Итак, я, очевидно, могу придумать несколько обходных путей для этого ... Я просто не уверен, что делает с идиоматическим C ++.

Должен ли я переопределить приращение так, чтобы попытка приращения лопатки приводила к лопатам? или может быть исключение?

Повторюсь: я определенно могу придумать несколько хакерских способов решить эту проблему. Я просто хочу, чтобы руководство опытных программистов сообщило мне, что, по их мнению, было бы наиболее "нормальным" способом решения проблемы.

Ответы [ 4 ]

2 голосов
/ 07 октября 2010

Вы можете добавить enum значения для условий запуска и завершения и альтернативу ++, которая не возвращается к началу.

enum Suit { FirstSuit, Clubs = FirstSuit, Diamonds, Hearts, Spades, AllSuits };

for ( suit i = FirstSuit; i != AllSuits; i = iterate_suits( i ) )

С for и whileЦиклы всегда проверяют условие перед выполнением, нет способа завершить их выполнение в середине циклического диапазона без дополнительных переменных или управления потоком.Цикл do while работает лучше всего в этом случае.

Suit iter_suit = my_suit; // iterate over all suits beginning with my_suit.
do {
} while ( ++ iter_suit != my_suit );

В этом случае вам не нужны FirstSuit и AllSuits.

1 голос
/ 07 октября 2010

Как предлагается в комментарии, как насчет определения вашего перечисления как:

enum Suit {Clubs, Diamonds, Hearts, Spades, EndSuit};

Тогда ваш цикл становится:

for(Suit i=Clubs;i<EndSuit;++i)
{
    cout<<i<<endl;
}
0 голосов
/ 07 октября 2010

Поскольку значения enum затухают в (без знака) целых чисел, вы можете использовать арифметику moduluo и затем приводить обратно к enum:

enum Suite add(const enum Suite card1, const enum Suite card 2)
{
 unsigned int result = card1;
 result += card2;
 result = result % 4;
 return (enum Suite) result;  // Casting shown for readability.
}

Предложение: превратить это в класс.С помощью класса вы также можете добавить методы «print» и «input».

0 голосов
/ 07 октября 2010

Возможно

enum Suit {Clubs, Diamonds, Hearts, Spades, NumberOfSuits};

for(Suit i=Clubs;i<NumberOfSuits;++i)
 {cout<<i<<endl;}

Есть еще что-то однотипное (я должен знать, что трефы - первая масть).

Почему бы просто не использовать неявное преобразование в int?

for (int i = 0; i < NumberOfSuits; ++i)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...