Burada, bireysel numaralandırma değerleri için gerçekten bir kullanımınız yoksa (örneğin, bunları kapatmanız gerekmez) bitma maskeleri için bir seçenek ... ve ikili uyumluluğu korumak konusunda endişelenmiyorsanız, yani: bitlerinizin nerede yaşadığı umurumda değil ... muhtemelen sizsiniz. Ayrıca, kapsam belirleme ve erişim kontrolü ile fazla ilgilenmemeniz daha iyi olur. Hmmm, numaralandırmalar bit alanları için bazı güzel özelliklere sahip ... merak ediyorum kimse bunu denediniz mi :)
struct AnimalProperties
{
bool HasClaws : 1;
bool CanFly : 1;
bool EatsFish : 1;
bool Endangered : 1;
};
union AnimalDescription
{
AnimalProperties Properties;
int Flags;
};
void TestUnionFlags()
{
AnimalDescription propertiesA;
propertiesA.Properties.CanFly = true;
AnimalDescription propertiesB = propertiesA;
propertiesB.Properties.EatsFish = true;
if( propertiesA.Flags == propertiesB.Flags )
{
cout << "Life is terrible :(";
}
else
{
cout << "Life is great!";
}
AnimalDescription propertiesC = propertiesA;
if( propertiesA.Flags == propertiesC.Flags )
{
cout << "Life is great!";
}
else
{
cout << "Life is terrible :(";
}
}
Hayatın harika olduğunu görebiliriz, ayrık değerlerimiz var ve hoş bir int var & & | hala bitlerinin ne anlama geldiğinin bağlamına sahip olan kalpler içeriğimize. Win10 x64'te Güncelleme 3 ile Microsoft'un VC ++ derleyicisini kullanmaya devam ettiğim ve derleyici bayraklarına dokunmadığım sürece her şey tutarlı ve tahmin edilebilir ... benim için ...
Her şey harika olsa da ... şimdi bayrakların anlamıyla ilgili bir bağlamımız var , çünkü programınızın yapabileceğiniz tek bir ayrı görevden daha fazla sorumlu olabileceği korkunç gerçek dünyadaki bit alanında bir birliktelik var. hala yanlışlıkla (oldukça kolay) farklı sendikaların iki bayrak alanını birlikte parçalayın (her ikisi de ints oldukları için AnimalProperties ve ObjectProperties), tüm parçalarınızı karıştırın, bu da izini sürmek korkunç bir böcek ... ve nasıl bildiğimi Bu yazıdaki birçok insan bitmasklarla çok sık çalışmaz, çünkü onları oluşturmak kolaydır ve onları korumak zordur.
class AnimalDefinition {
public:
static AnimalDefinition *GetAnimalDefinition( AnimalFlags flags ); //A little too obvious for my taste... NEXT!
static AnimalDefinition *GetAnimalDefinition( AnimalProperties properties ); //Oh I see how to use this! BORING, NEXT!
static AnimalDefinition *GetAnimalDefinition( int flags ); //hmm, wish I could see how to construct a valid "flags" int without CrossFingers+Ctrl+Shift+F("Animal*"). Maybe just hard-code 16 or something?
AnimalFlags animalFlags; //Well this is *way* too hard to break unintentionally, screw this!
int flags; //PERFECT! Nothing will ever go wrong here...
//wait, what values are used for this particular flags field? Is this AnimalFlags or ObjectFlags? Or is it RuntimePlatformFlags? Does it matter? Where's the documentation?
//Well luckily anyone in the code base and get confused and destroy the whole program! At least I don't need to static_cast anymore, phew!
private:
AnimalDescription m_description; //Oh I know what this is. All of the mystery and excitement of life has been stolen away :(
}
Böylece, sendika beyanınızı "Bayraklar" a doğrudan erişimi önlemek için gizli hale getirirsiniz ve alıcılar / ayarlayıcılar ve operatör aşırı yüklemeleri eklemeniz gerekir, ardından tüm bunlar için bir makro oluşturursunuz ve temel olarak, denediğinizde başladığınız yere geri dönersiniz. bunu bir Enum ile yap.
Ne yazık ki kodunuzun taşınabilir olmasını istiyorsanız, A) bit düzenini garanti etmenin veya B) derleme zamanında bit düzenini belirlemenin (böylece onu izleyebilmeniz ve en azından sürümler / platformlar vb.)
Bit alanlı bir yapıda ofset
Çalışma zamanında, alanları ayarlayarak hileler oynayabilir ve hangi bitlerin değiştiğini görmek için bayrakları XORing yapabilirsiniz,% 100 tutarlı, platformdan bağımsız ve tamamen deterministik bir çözüme sahip olan ayetler bana oldukça bok gibi geliyor: ENUM.
TL; DR: Nefret dinlemeyin. C ++ İngilizce değildir. C'den devralınan kısaltılmış bir anahtar kelimenin gerçek tanımının kullanımınıza uymaması , anahtar kelimenin C ve C ++ tanımı kesinlikle kullanım durumunuzu içerdiğinde kullanmamanız gerektiği anlamına gelmez . Yapıları yapı dışındaki yapıları modellemek için yapıları, okul ve sosyal kast dışındaki yapıları da sınıflamak için kullanabilirsiniz. Topraklanmış değerler için şamandıra kullanabilirsiniz. Char'ı yanmayan veya bir roman, oyun veya filmdeki bir kişi için kullanabilirsiniz. Dil spesifikasyonundan önce bir anahtar kelimenin anlamını belirlemek için sözlüğe giden herhangi bir programcı ... bir dilimi orada tutacağım.
Kodunuzun konuşulan dilden sonra modellenmesini istiyorsanız, en çok bitfields için enum'ları da kullanan Objective-C'de yazmaktan daha iyi olursunuz.
[Flags]
özellik gayet iyi çalışıyor:[Flags] enum class FlagBits{ Ready = 1, ReadMode = 2, WriteMode = 4, EOF = 8, Disabled = 16};