Перечисления уровня пространства имен в c ++ - PullRequest
4 голосов
/ 04 ноября 2011

Плохо ли иметь перечисления в c ++ непосредственно на уровне пространства имен?Я имею в виду не связаны с каким-либо классом?Скажите, если у меня есть enum и класс, который выглядит примерно так:

enum Player { USER, COMPUTER}

class Game {
//Logic of the game.
};

Так я должен объявлять перечисление Player как члена класса игры?Это должно быть личное?

Ответы [ 6 ]

11 голосов
/ 04 ноября 2011

С С ++ 11

Этот ответ был первоначально написан в 2011 году. Теперь, когда поддержка C ++ 11 широко доступна, предпочтительным способом является использование enum class, как указывает Мэтью Д. Сколфилд ниже:

enum class Player {
    User,
    Computer
};

Перечисленные константы должны указывать имя перечисления при ссылке (например, Player::Computer).

До C ++ 11

Нет, в общедоступном enum нет ничего плохого. Имейте в виду, однако, что перечисляемые константы не могут быть квалифицированы по имени типа enum. То есть вы не можете написать Player::USER или что-то подобное для ссылки на константу USER; они появляются прямо во вложенном пространстве имен. Таким образом, было бы неплохо установить префикс для ваших констант, чтобы не возникало конфликтов имен.

Например, рассмотрим следующую декларацию:

enum Player {
  PL_USER,
  PL_COMPUTER
}

Это безопаснее, потому что коллизии имен гораздо реже с префиксом "PL_". Кроме того, он улучшает читабельность кода, подсказывая, какому перечислению принадлежит данная константа.

В таких языках, как C # и Java, применяется несколько иной подход к перечислениям, в котором необходимо указывать как имя перечисления, так и имя константы, например Player.USER. Подобный эффект может быть достигнут в C ++, встраивая объявление enum в собственное пространство имен. Например:

namespace Player {
  enum Type {
    USER,
    COMPUTER
  }
}

Это дает эффект встраивания PLAYER и COMPUTER в пространство имен Player вместо глобального (или иного включения) пространства имен. Является ли это хорошим подходом или нет, по моему мнению, является вопросом предпочтения.

3 голосов
/ 04 ноября 2011

Как правило, используйте минимальный объем для всего.

Это облегчает понимание вещей.

Однако, ясность или отсутствие из-за размещения этого enum внутри или вне класса, ничто по сравнению с криком , использованием ВСЕХ ИДЕНТИФИКАТОРОВ ВЕРХНЕГО ПОКАЗАТЕЛЯ Зарезервируйте те для макросов. В Java они используются для констант, потому что Java получила свой внешний вид от C, где не так уж необычно определять константы как макросы (потому что ранний C не имел const). Обратите внимание, что в Java нет препроцессора и макросов. Более чем глупо принимать соглашение, которое возникло в C, для хранения макросов в отдельном «пространстве имен» и применения его без понимания к чему-то другому, чтобы полностью совпадать с первоначальным намерением.

Приветствия & hth.,

2 голосов
/ 04 ноября 2011

Если используется enum Player ...

  • только в пределах class Game -> положить в личное область действия
  • используется class Game и его дочерними классами -> помещается в protected scope
  • Это относится к class Game и используется в различных местах -> положить в общедоступных сферах
  • Нигде не относится к Game -> положить в global / namespace scope
1 голос
/ 04 ноября 2011

Это чисто вопрос предпочтений; однако я склонен использовать Java-подобные перечисления в C ++:

class PlayerType {
  public:
     enum VALUE {USER, COMPUTER};
     explicit PlayerType(VALUE val) : value_(val) {}

     operator VALUE() const { return value_; }
     bool operator==(VALUE other) const { return value_ == other; }
     bool operator!=(VALUE other) const { return value_ != other; }
  private:
     VALUE value_;
     // Copy and assign intentionally allowed.
};

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

0 голосов
/ 04 ноября 2011

Лучше определить enum в пространстве имен

0 голосов
/ 04 ноября 2011

Если бы он использовался только внутри класса Game, я бы поместил в него enum.

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