W poniższym fragmencie kodu Color
wyliczenie jest zadeklarowane w Car
klasie, aby ograniczyć zakres wyliczenia i nie „zanieczyszczać” globalnej przestrzeni nazw.
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) Czy to dobry sposób na ograniczenie zakresu Color
wyliczenia? A może powinienem zadeklarować go poza Car
klasą, ale prawdopodobnie w jego własnej przestrzeni nazw lub strukturze? Właśnie dziś trafiłem na ten artykuł, który opowiada się za tym drugim i omawia kilka fajnych punktów na temat wyliczeń: http://gamesfromwithin.com/stupid-c-tricks-2-better-enums .
(2) W tym przykładzie, podczas pracy w klasie, czy najlepiej jest zakodować wyliczenie jako Car::Color
, czy po prostu Color
wystarczy? (Zakładam, że to pierwsze jest lepsze, na wypadek gdyby Color
w globalnej przestrzeni nazw zadeklarowano inne wyliczenie. W ten sposób przynajmniej jasno określamy wyliczenie, do którego się odnosimy).
Car::Color getColor()
alevoid Car::setColor(Color c)
ponieważsetColor
mamy już specyfikator.Obecnie - używając C ++ 11 - możesz użyć do tego klasy enum :
AFAII to robi dokładnie to, co chcesz.
źródło
Wolę następujące podejście (kod poniżej). Rozwiązuje problem "zanieczyszczenia przestrzeni nazw", ale jest też dużo bardziej bezpieczny dla typów (nie możesz przypisać, a nawet porównać dwóch różnych wyliczeń lub wyliczenia z innymi wbudowanymi typami itp.).
Stosowanie:
Tworzę makro w celu ułatwienia użytkowania:
Stosowanie:
Niektóre odniesienia:
źródło
if(c2 == Color::Red )
jest rozsądna i musi się skompilować, ale w twoim przykładzie jest to nie. Ten sam argument dla przypisania również!c2
jest innego typu (Color2
), więc jak myślisz, dlaczegoc2 == Color::Red
przypisania powinny się kompilować? A jeśliColor::Red
jest 1, aColor2::Red
to 2? PowinienColor::Red == Color2::Red
ocenićtrue
lubfalse
? Jeśli pomieszasz niezabezpieczone typy wyliczające, będziesz się źle bawić.Ogólnie rzecz biorąc, zawsze umieszczam wyliczenia w pliku
struct
. Widziałem kilka wskazówek, w tym „prefiksowanie”.Zawsze uważałem, że wygląda to bardziej jak
C
wytyczne niżC++
jedne (na przykład ze względu na skrót, a także ze względu na przestrzenie nazw wC++
).Aby ograniczyć zakres, mamy teraz dwie alternatywy:
Osobiście zwykle używam a,
struct
ponieważ może być używany jako parametr do programowania szablonów, podczas gdy przestrzenią nazw nie można manipulować.Przykłady manipulacji obejmują:
która zwraca liczbę elementów enum wewnątrz struktury
T
:)źródło
Jeśli tworzysz bibliotekę kodu, użyłbym przestrzeni nazw. Jednak w tej przestrzeni nazw nadal można mieć tylko jedno wyliczenie koloru. Jeśli potrzebujesz wyliczenia, które może używać wspólnej nazwy, ale może mieć różne stałe dla różnych klas, użyj swojego podejścia.
źródło