Подтвердить что ты не робот

Должны ли вы объявлять перечисления внутри или вне класса?

Должны ли вы объявлять перечисления внутри или вне класса, если указанные перечисления используются только в функциях членов класса?

namespace nspace
{

// need to append OC, as this pollutes the current namespace
enum OUTSIDE_CLASS {OC_POINTS, OC_LINES, OC_LINE_LOOP, :::};
enum OTHER_ENUM {OE_POINTS};
class VertexBuffer
{
public:
    enum INSIDE_CLASS {POINTS, LINES, LINE_LOOP, :::};
    void foo(OUTSIDE_CLASS e);
    void bar(INSIDE_CLASS e);
}
};

// usage
nspace::VertexBuffer v;
v.foo(nspae::VB_POINTS);
v.bar(nspace::VertexBuffer::POINTS); // more pedantic
4b9b3361

Ответ 1

Реальная цель состоит в том, чтобы не загрязнять область (глобальное или пространство имен) и группировать связанные между собой значения вместе (работает с товарами с автозавершением в среде IDE).

С С++ 11 вы можете объявить строго типизированные перечисления, используя:

enum class MyEnum {
  Value0,
  Value1
};

которые обязательно вызываются как MyEnum::Value0 (а не Value0).

В С++ 03 вы можете более или менее эмулировать это с помощью:

struct MyEnum {
  enum Type {
    Value0,
    Value1
  };
};

Но тогда тип перечисления MyEnum::Type, который является немного отличающимся.

Ленивый вариант состоит в том, чтобы просто сбрасывать его в классе, но я все же предпочитаю вложенное перечисление с областью, даже внутри класса, просто чтобы было ясно, что эти значения не потеряны, а вместо этого взаимосвязаны.

Ответ 2

Если только члены вашего класса используют enum, желательно объявить enum внутри класса.
Это предотвращает загрязнение пространства имен/глобального пространства из-за ненужных имен символов, а также Он более интуитивен для пользователей этого класса, он помогает пользователю узнать, что enum будет использоваться только классом.

Следующее общее правило:
Не добавляйте символ в область (глобальное/пространство имен), к которой не будет доступ (и, следовательно, не требуется) в этой области.

Ответ 3

Как упоминал Маттиу М., в С++ 11 используйте Сильно типизированные перечисления.

Хороший способ имитировать их в С++ 03 - это перенос перечислений в пространства имен. Это лучше, чем обертывание в struct, потому что это пространство имен может иметь функции, которые можно найти, используя зависящий от аргумента поиск имени. Например:.

namespace MyEnum {
  enum Type {
    Value0,
    Value1
  };

  std::ostream& operator<<(std::ostream&, Type);
  std::istream& operator>>(std::istream&, Type&);
}

MyEnum::Type value;
std::cout << value; // uses the overload from MyEnum
std::cin >> value; // uses the overload from MyEnum

Ответ 4

Это зависит. Стремитесь минимизировать воздействие деталей реализации. Например. заключать вещи в пространствах имен и/или классы и/или отдельно скомпилированные файлы реализации. И, как мы надеемся, очень ясно, глобальное пространство имен и класс в целом - это совсем не единственные варианты. Я., объявляя что-то в классе, не единственный способ свести к минимуму воздействие (каковы некоторые другие способы? --- о, ну, помните третье предложение этого ответа).