В следующем фрагменте кода Color
перечисление объявляется внутри Car
класса, чтобы ограничить область действия перечисления и попытаться не «загрязнять» глобальное пространство имен.
class Car
{
public:
enum Color
{
RED,
BLUE,
WHITE
};
void SetColor( Car::Color color )
{
_color = color;
}
Car::Color GetColor() const
{
return _color;
}
private:
Car::Color _color;
};
(1) Это хороший способ ограничить область действия Color
перечисления? Или я должен объявить это вне Car
класса, но, возможно, в его собственном пространстве имен или структуре? Я только что наткнулся на эту статью сегодня, которая поддерживает последнюю и обсуждает некоторые приятные моменты о перечислениях: http://gamesfromwithin.com/stupid-c-tricks-2-better-enums .
(2) В этом примере при работе в классе лучше всего кодировать перечисление как Car::Color
, или этого будет Color
достаточно? (Я предполагаю, что первое лучше, на случай, если Color
в глобальном пространстве имен объявлен другой enum. Таким образом, по крайней мере, мы явно говорим о перечислении, на которое мы ссылаемся.)
Car::Color getColor()
аvoid Car::setColor(Color c)
потому что уsetColor
нас уже есть спецификатор.В настоящее время - используя C ++ 11 - вы можете использовать для этого класс enum :
AFAII это делает именно то, что вы хотите.
источник
Я предпочитаю следующий подход (код ниже). Он решает проблему «загрязнения пространства имен», но также он намного более безопасен для типов (вы не можете назначать и даже сравнивать два различных перечисления или ваше перечисление с любыми другими встроенными типами и т. Д.).
Использование:
Я создаю макрос для облегчения использования:
Использование:
Некоторые ссылки:
источник
if(c2 == Color::Red )
она разумна и должна компилироваться, но в вашем примере это не. Тот же аргумент для назначения также!c2
относится к другому типу (Color2
), так почему вы думаете, чтоc2 == Color::Red
задания должны компилироваться? Что еслиColor::Red
1, аColor2::Red
2? СледуетColor::Red == Color2::Red
оценитьtrue
илиfalse
? Если вы смешиваете нетипобезопасные счетчики, у вас будет плохое время.В общем, я всегда помещаю свои перечисления в
struct
. Я видел несколько рекомендаций, включая «префикс».Всегда думал, что это больше похоже на
C
рекомендации, чем наC++
них (например, из-за аббревиатуры, а также из-за пространств имен вC++
).Таким образом, чтобы ограничить область применения, у нас теперь есть две альтернативы:
Лично я склонен использовать a,
struct
потому что он может использоваться в качестве параметров для программирования шаблонов, в то время как пространством имен нельзя манипулировать.Примеры манипуляции включают в себя:
который возвращает количество элементов enum внутри структуры
T
:)источник
Если вы создаете библиотеку кода, то я бы использовал пространство имен. Тем не менее, вы можете иметь только одно перечисление Color внутри этого пространства имен. Если вам нужен enum, который может использовать общее имя, но может иметь разные константы для разных классов, используйте ваш подход.
источник