मुझे लगता है कि सी ++ यूनियनों बहुत अच्छा है। ऐसा लगता है कि लोग आमतौर पर केवल उपयोग के मामले के बारे में सोचते हैं जहां कोई "उदाहरण के लिए" (उदाहरण के लिए, ऐसा लगता है कि केवल स्मृति को बचाने या संदेहास्पद रूपांतरण करने के लिए कार्य करता है) के मूल्य को बदलना चाहता है।
वास्तव में, यूनियन एक सॉफ्टवेयर इंजीनियरिंग उपकरण के रूप में महान शक्ति के हो सकते हैं, तब भी जब आप किसी भी संघ उदाहरण के मूल्य को कभी नहीं बदलते हैं ।
केस 1 का प्रयोग करें: गिरगिट
यूनियनों के साथ, आप एक संप्रदाय के तहत कई मनमानी वर्गों को फिर से इकट्ठा कर सकते हैं, जो आधार वर्ग और इसके व्युत्पन्न वर्गों के मामले के साथ समानता के बिना नहीं है। हालाँकि, क्या बदलाव है, जो आप किसी दिए गए यूनियन उदाहरण के साथ कर सकते हैं और नहीं कर सकते हैं:
struct Batman;
struct BaseballBat;
union Bat
{
Batman brucewayne;
BaseballBat club;
};
ReturnType1 f(void)
{
BaseballBat bb = {/* */};
Bat b;
b.club = bb;
// do something with b.club
}
ReturnType2 g(Bat& b)
{
// do something with b, but how do we know what's inside?
}
Bat returnsBat(void);
ReturnType3 h(void)
{
Bat b = returnsBat();
// do something with b, but how do we know what's inside?
}
ऐसा प्रतीत होता है कि प्रोग्रामर को किसी दिए गए यूनियन उदाहरण की सामग्री के प्रकार के बारे में निश्चित होना चाहिए जब वह इसका उपयोग करना चाहता है। यह f
ऊपर फ़ंक्शन में मामला है । हालाँकि, यदि कोई फ़ंक्शन पास किए गए तर्क के रूप में एक संघ उदाहरण प्राप्त करना था, जैसा कि g
ऊपर के मामले में है, तो यह नहीं जानता कि इसके साथ क्या करना है। संघ के उदाहरणों को लौटाने वाले फ़ंक्शन पर भी यही लागू होता है, देखें h
: कॉलर को कैसे पता चलता है कि उसके अंदर क्या है?
यदि कोई संघ उदाहरण तर्क या रिटर्न मान के रूप में कभी भी पास नहीं होता है, तो यह एक बहुत नीरस जीवन के लिए बाध्य है, उत्साह के स्पाइक्स के साथ जब प्रोग्रामर अपनी सामग्री को बदलने का विकल्प चुनता है:
Batman bm = {/* */};
Baseball bb = {/* */};
Bat b;
b.brucewayne = bm;
// stuff
b.club = bb;
और यह यूनियनों का सबसे (संयुक्त राष्ट्र) लोकप्रिय उपयोग मामला है। एक अन्य उपयोग मामला तब है जब एक संघ उदाहरण कुछ के साथ आता है जो आपको अपना प्रकार बताता है।
मामले 2 का उपयोग करें: "आपसे मिलकर अच्छा लगा, मैं कर रहा हूँ object
, से Class
"
मान लें कि एक प्रोग्रामर को हमेशा एक प्रकार के डिस्क्रिप्टर के साथ एक यूनियन उदाहरण के लिए चुना जाता है (मैं एक ऐसे ऑब्जेक्ट के लिए कार्यान्वयन की कल्पना करने के लिए पाठक के विवेक पर छोड़ दूंगा)। यह स्वयं संघ के उद्देश्य को हरा देता है यदि प्रोग्रामर स्मृति को बचाना चाहता है और यह कि संघ के संबंध में टाइप डिस्क्रिप्टर का आकार नगण्य नहीं है। लेकिन मान लें कि यह महत्वपूर्ण है कि संघ के उदाहरण को एक तर्क के रूप में पारित किया जा सकता है या कैली या कॉलर के साथ वापसी मूल्य के रूप में कहा जा सकता है कि यह अंदर नहीं है।
फिर प्रोग्रामर को switch
ब्रूस वेन को लकड़ी की छड़ी, या कुछ समतुल्य बताने के लिए एक नियंत्रण प्रवाह विवरण लिखना होगा । यह बहुत बुरा नहीं है जब संघ में केवल दो प्रकार की सामग्री होती है, लेकिन जाहिर है, संघ अब कोई पैमाना नहीं है।
केस 3 का उपयोग करें:
आईएसओ सी ++ मानक के लिए एक सिफारिश के लेखकों के रूप में इसे 2008 में वापस रखा गया,
कई महत्वपूर्ण समस्या डोमेन को बड़ी संख्या में ऑब्जेक्ट या सीमित मेमोरी संसाधनों की आवश्यकता होती है। इन स्थितियों में अंतरिक्ष का संरक्षण बहुत महत्वपूर्ण है, और एक संघ अक्सर ऐसा करने का एक सही तरीका है। वास्तव में, एक सामान्य उपयोग मामला वह स्थिति है जहां एक संघ अपने जीवनकाल के दौरान अपने सक्रिय सदस्य को कभी नहीं बदलता है। इसका निर्माण, नकल और विनाश हो सकता है जैसे कि यह एक संरचना है जिसमें केवल एक सदस्य होता है। इसका एक विशिष्ट अनुप्रयोग असंबंधित प्रकार के विषम संग्रह बनाना होगा जो गतिशील रूप से आवंटित नहीं होते हैं (शायद वे एक नक्शे में निर्मित हैं, या किसी सरणी के सदस्य हैं)।
और अब, एक उदाहरण, एक यूएमएल वर्ग आरेख के साथ:
सादे अंग्रेजी में स्थिति: कक्षा एक की एक वस्तु कर सकते हैं बी 1 के बीच किसी भी वर्ग की वस्तुओं है, ..., बटालियन, और प्रत्येक प्रकार के सबसे एक, के साथ कम से n एक बहुत बड़ी संख्या होने के नाते, का कहना है कि कम से कम 10।
हम ए की तरह फ़ील्ड (डेटा सदस्य) जोड़ना नहीं चाहते हैं:
private:
B1 b1;
.
.
.
Bn bn;
क्योंकि n भिन्न हो सकते हैं (हम मिश्रण में Bx कक्षाएं जोड़ना चाहते हैं), और क्योंकि इससे निर्माणकर्ताओं के साथ गड़बड़ी होगी और क्योंकि A ऑब्जेक्ट में बहुत अधिक जगह होगी।
हम एक निराला कंटेनर इस्तेमाल कर सकते हैं void*
की ओर इशारा Bx
डाले के साथ वस्तुओं के लिए उन्हें पुनः प्राप्त करने, लेकिन वह fugly और इतने सी शैली है ... लेकिन अधिक महत्वपूर्ण बात यह है कि हम कई गतिशील आवंटित वस्तुओं के जीवन काल का प्रबंधन करने के साथ छोड़ जाएगा।
इसके बजाय, क्या किया जा सकता है:
union Bee
{
B1 b1;
.
.
.
Bn bn;
};
enum BeesTypes { TYPE_B1, ..., TYPE_BN };
class A
{
private:
std::unordered_map<int, Bee> data; // C++11, otherwise use std::map
public:
Bee get(int); // the implementation is obvious: get from the unordered map
};
फिर, एक संघ उदाहरण की सामग्री प्राप्त करने के लिए data
, आप उपयोग करते हैं a.get(TYPE_B2).b2
और पसंद करते हैं, जहां a
एक वर्ग A
उदाहरण है।
यह सभी अधिक शक्तिशाली है क्योंकि यूनियनों को C ++ 11 में अप्रतिबंधित किया गया है। देखें दस्तावेज़ ऊपर से जुड़ा हुआ या इस लेख जानकारी के लिए।