यदि आप वास्तव में व्यक्तिगत एनम मूल्यों के लिए उपयोग नहीं करते हैं (उदाहरण के लिए, आपको उनमें से स्विच करने की आवश्यकता नहीं है) ... और यदि आप द्विआधारी संगतता बनाए रखने के बारे में चिंतित नहीं हैं, तो आपके लिए यह विकल्प है: आप परवाह मत करो कि आपके बिट्स कहाँ रहते हैं ... जो आप शायद हैं। इसके अलावा आप बेहतर तरीके से स्कूपिंग और एक्सेस कंट्रोल से भी चिंतित नहीं होंगे। हम्म, एनमों में बिट-फील्ड के लिए कुछ अच्छे गुण हैं ... आश्चर्य है कि अगर किसी ने कभी कोशिश की है कि :)
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 :(";
}
}
हम देख सकते हैं कि जीवन महान है, हमारे पास हमारे असतत मूल्य हैं, और हमारे पास & | हमारे दिल की सामग्री, जो अभी भी इसके बिट्स का क्या अर्थ है का संदर्भ है। सब कुछ सुसंगत और पूर्वानुमेय है ... मेरे लिए ... जब तक मैं Microsoft के VC ++ कंपाइलर w / अपडेट 3 का उपयोग Win10 x64 पर करता रहता हूं और अपने कंपाइलर झंडे को नहीं छूता हूं :)
भले ही सब कुछ महान हो ... हमारे पास झंडे के अर्थ के रूप में कुछ संदर्भ हैं, क्योंकि इसके संघ में w / भयानक वास्तविक दुनिया में बिटफील्ड है जहां आपका कार्यक्रम एक से अधिक असतत कार्य के लिए जिम्मेदार हो सकता है अभी भी अकस्मात (काफी आसानी से) अलग-अलग यूनियनों के दो झंडे वाले क्षेत्रों को एक साथ तोड़ते हैं (जैसे, AnimalProperties और ObjectProperties, क्योंकि वे दोनों चींटियां हैं), आपके सभी बिट्स को मिलाते हैं, जो नीचे ट्रेस करने के लिए एक भयानक बग है ... और कैसे वे जानते हैं इस पोस्ट पर बहुत से लोग बहुत बार बिटमास्क के साथ काम नहीं करते हैं, क्योंकि उन्हें बनाना आसान है और उन्हें बनाए रखना कठिन है।
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 :(
}
तो फिर आप "फ़्लैग" की सीधी पहुंच को रोकने के लिए अपनी यूनियन घोषणा को निजी बनाते हैं, और गेटर्स / सेटर और ऑपरेटर ओवरलोड्स को जोड़ना पड़ता है, फिर उस सब के लिए एक मैक्रो बनाते हैं, और आप मूल रूप से ठीक पीछे हैं जहां आपने शुरू किया था जब आपने प्रयास किया था एक Enum के साथ यह करो।
दुर्भाग्य से अगर आप चाहते हैं कि आपका कोड पोर्टेबल हो, तो मुझे नहीं लगता कि ए के पास कोई रास्ता है) बिट लेआउट की गारंटी दें या बी) संकलन समय पर थोड़ा लेआउट निर्धारित करें (ताकि आप इसे ट्रैक कर सकें और कम से कम बदलावों के लिए सही कर सकें संस्करणों / प्लेटफार्मों आदि)
बिट क्षेत्रों के साथ एक संरचना में ऑफसेट
रनटाइम पर आप ट्रिक w / फ़ील्ड्स सेट कर सकते हैं और झंडे को XOR कर सकते हैं यह देखने के लिए कि किन बिट्स ने बदलाव किया है, मुझे बहुत भद्दा लगता है हालांकि 100% सुसंगत, प्लेटफ़ॉर्म स्वतंत्र, और पूरी तरह से नियतात्मक समाधान अर्थात: ENUM।
TL; DR: नफरत करने वालों की बात मत सुनो। C ++ अंग्रेजी नहीं है। सिर्फ इसलिए कि C से विरासत में प्राप्त एक संक्षिप्त कीवर्ड की शाब्दिक परिभाषा आपके उपयोग के लायक नहीं है, इसका मतलब यह नहीं है कि आप इसका उपयोग तब नहीं करें जब कीवर्ड की C और C ++ परिभाषा में आपके उपयोग का मामला पूरी तरह से शामिल हो। आप संरचनाओं के अलावा अन्य चीजों के मॉडल और स्कूल और सामाजिक जाति के अलावा अन्य चीजों के लिए कक्षाओं का उपयोग कर सकते हैं। आप फ्लोट का उपयोग उन मूल्यों के लिए कर सकते हैं जो ग्राउंडेड हैं। आप चर का उपयोग कर सकते हैं जो न तो जले हुए हैं और न ही किसी उपन्यास, नाटक या फिल्म में कोई व्यक्ति। कोई भी प्रोग्रामर जो भाषा की युक्ति से पहले किसी कीवर्ड का अर्थ निर्धारित करने के लिए शब्दकोश में जाता है ... अच्छी तरह से मैं अपनी जीभ वहाँ रखूँगा।
यदि आप चाहते हैं कि आपका कोड बोली जाने वाली भाषा के बाद तैयार किया जाए, तो आप ऑब्जेक्टिव-सी में लिखना बंद कर देंगे, जो संयोगवश बिटफिल्ड्स के लिए एनम का भारी उपयोग करता है।
[Flags]
विशेषता ठीक काम करती है:[Flags] enum class FlagBits{ Ready = 1, ReadMode = 2, WriteMode = 4, EOF = 8, Disabled = 16};