2012-10-24 4 views
6

मैं यह काम नहीं करता हैरान हूँ:क्या मैं एक यादगार प्रारंभकर्ता में एक संघ शुरू कर सकता हूं?

union DlDatum 
{ 
    float mFloat; 
    s32 mInteger; 
}; 

class DlDbE 
{ 
public: 
    DlDbE(float f) : mData.mFloat(f) {}; 
private: 
    DlDatum mData; 
}; 

वहाँ एक C++ निर्माता मेम-प्रारंभकर्ता सूची में एक संघ प्रारंभ करने के लिए एक रास्ता है?

अद्यतन: उत्तर संघ के लिए रचनाकार बनाना है। नहीं पता था कि किया जा सकता है। यदि आप एक संघ का निर्माण करना चाहते हैं, तो आप संघ एक निर्माता देने के लिए और फोन है कि करना होगा

union DlDatum 
{ 
    float mFloat; 
    s32 mInteger; 
    bool mBoolean; 
    u32 mSymbol; 
    u32 mObjIdx; 

    DlDatum(  ) : mInteger(0) {} 
    DlDatum(float f) : mFloat(f) {} 
    DlDatum(s32 i) : mInteger(i) {} 
    DlDatum(bool b) : mBoolean(b) {} 
    DlDatum(u32 s) : mSymbol(s) {} // this ctor should work for objIdx also 
}; 

class DlDbE 
{ 
public: 
    DlDbE() {} 
    DlDbE(float f) : mData(f) {} 
    DlDbE(u32 i ) : mData(i) {} 
    DlDbE(bool b ) : mData(b) {} 
    ...etc.. 
private: 
    DlDatum mData; 
}; 
+0

http://stackoverflow.com/questions/321351/initializing-a-union-with-a-non-trivial-constructor – Mysticial

उत्तर

11

किसी अन्य सदस्य की तरह,: यहाँ मैं क्या किया है।

+0

पता नहीं था कि यूनियनों में रचनाकार हो सकते हैं। मैं कोशिश करूँगा। क्या उनके पास सदस्य हो सकते हैं? –

+0

@ राफेलबैपटिस्ट हां, बस वर्चुअल फ़ंक्शंस नहीं। वे किसी भी चीज़ से उत्तराधिकारी नहीं हो सकते हैं या विरासत में नहीं हो सकते हैं। –

+0

दिलचस्प। Gimped कक्षाओं की तरह। –

9

सी ++ 03 में और इससे पहले कि आप अपने संघ के लिए एक निर्माता लिखने तक सीमित हैं।

सी ++ 11 वर्दी प्रारंभिक कन्स्ट्रक्टर प्रारंभकर्ता सूचियों के समग्र प्रारंभिक के वाक्यविन्यास को बढ़ाता है। ऐसे ही

DlDatum d = { 3.0 }; 

जो हम सभी जानते हैं और सी से प्यार करते हैं और जो अच्छे पुराने कुल प्रारंभकर्ता वाक्य रचना संघ के पहले सदस्य initializes इसका मतलब यह है, अब के रूप में अच्छी

union DlDatum 
{ 
    float mFloat; 
    s32 mInteger; 
}; 

class DlDbE 
{ 
public: 
    DlDbE(float f) : mData{f} {} 
private: 
    DlDatum mData; 
}; 
निर्माता प्रारंभकर्ता सूचियों में इस्तेमाल किया जा सकता

यह सुविधा केवल आपको प्रारंभिकरण के लिए संघ के पहले गैर स्थैतिक सदस्य को "लक्षित" करने की अनुमति देती है। अगर आपको कुछ और लचीला चाहिए, तो यह रचनाकारों को लिखने के लिए वापस आ गया है।

1

@AndreyT एक उत्कृष्ट उत्तर देता है कि मैं थोड़ा व्यावहारिक सलाह के साथ विस्तार करूंगा।

मैं बिट्सैप मूल्य तक आसानी से पहुंचने के लिए यूनियनों का उपयोग करता हूं, बिना थकाऊ और बदसूरत बिटवाई और/bitwise या। मुझे लगता है कि यह एक काफी आम अभ्यास है।

एक तकनीक मैं थोड़ी देर के लिए इस्तेमाल किया है प्रक्रिया भी आसान है अगर मैं कम से कम 32bits की एक बिटमैप के साथ काम कर रहा हूँ मैं एक अनाम struct के रूप में यह घोषणा एक संघ अंदर एक साथी DWORD के साथ बनाने के लिए डेटा-सदस्य। उदाहरण के लिए:

union UNICODECONTROL{ 
    DWORD   dwAccessor; 
    struct{ 
     unsigned unicode_01 : 1; 
     unsigned unicode_02 : 1; 
     unsigned unicode_03 : 1; 
     unsigned unicode_04 : 1; 
     unsigned unicode_05 : 1; 
     unsigned unicode_06 : 1; 
     unsigned unicode_07 : 1; 
     unsigned unicode_08 : 1; 
     unsigned unicode_09 : 1; 
     unsigned unicode_10 : 1; 
    }; 
}; 

इसके साथ ही यह 'एक्सेसर' फ़ंक्शन की तरह काम करेगा। यदि आप मान सेट करना चाहते हैं तो आप इस 'एक्सेसर' पर उचित बिटमैप के साथ एक नंबर असाइन करके एक करके ऐसा कर सकते हैं। आप उन्हें सभी को शून्य करना चाहते हैं - केक का एक टुकड़ा भी। यह विशेष रूप से विंडोज रजिस्ट्री के साथ बहुत अच्छी तरह से काम करता है। यूनियन बिटमैप के मूल्य को स्टोर करने के लिए आपको बस इतना करना है कि रजिस्ट्री में DWORD लिखें! पुन: प्रारंभ करने के लिए बाद में इसे पुनः प्राप्त करना उतना ही सरल है।

DWORD रजिस्ट्री के मूल प्रकारों में से एक है और आपको स्थैतिक-कास्टिंग या मैन्युअल रूपांतरण कार्यों को लिखने की आवश्यकता नहीं है। यदि आपके पास 32 बिट्स से अधिक बिटमैप है तो आप 64 बिट आकार के पूर्णांक की घोषणा कर सकते हैं और यह सामान्य रूप से उसी तरह काम करेगा - और QUADWORD के रूप में रजिस्ट्री के साथ समान रूप से अच्छी तरह से एक मूल प्रकार है।

जहां इस सीधे भालू @AndreyT क्या उल्लेख पर - अगर आप मेरी संघ-बिटमैप/DWORD प्रारूप में एक वर्ग डेटा सदस्यीय की सुविधाजनक प्रारंभ करना चाहते हैं, तुम सब करने की है - उदाहरण के रूप में - यह सुनिश्चित कर लें संघ में घोषित पहला मूल्य 'एक्सेसर' है। फिर आप इसे नई सी ++ 11 '{}' योजना के साथ सीधे याद कर सकते हैं। अजीब संघ-रचनाकारों की बिल्कुल आवश्यकता नहीं है!

एक चेतावनी। जहां अलग बिटमैप बिट्स 'अंदर' रहते हैं तो एक्सेसर DWORD आपके संरचनाओं के लिए संरेखण सेटिंग पर निर्भर करेगा। यह संकलक स्तर पर या MS12 ++ में __declspec(align(#)) कथन और अन्य कंपाइलरों में समान वाक्यविन्यास के साथ सेट किया गया है।

अंत में, हाल ही में कई अलग-अलग परिदृश्यों में इन विचारों को आजमाते हुए एक अपडेट सीखा। तथ्य यह है कि सी ++ 11 स्पष्ट रूप से कहता है कि ऊपर वर्णित अनुसार अपने पहले चर द्वारा यूनियन को प्रारंभ करना कानूनी है, एमएसवीसी ++ इस मानक को अनदेखा करता है - या ' लागू नहीं करता है' क्योंकि यह संकलक त्रुटि आउटपुट कहता है। इसलिए यदि आप माइक्रोसॉफ्ट कंपाइलर का उपयोग कर रहे हैं तो आपको अपने यूनियन के लिए एक गन्दा कन्स्ट्रक्टर लागू करना होगा यदि आप इसे प्रारंभ करना चाहते हैं। शर्म की बात है, लेकिन संभवतः सी ++ 11 मानक का अनुपालन वीएस2013 को और सर्विस आईडी में और अगले आईडीई के अगले 2014 पुनरावृत्ति के साथ बेहतर होगा।

संबंधित मुद्दे