2008-10-16 12 views
14

मैं एक वर्ग बनाने की प्रक्रिया में हूं जो किसी विशेष डेटा स्रोत के बारे में मेटाडेटा संग्रहीत करता है। मेटाडाटा एक पेड़ में संरचित होता है, जो एक्सएमएल की संरचना के समान ही होता है। मेटाडेटा मान पूर्णांक, दशमलव, या स्ट्रिंग मान हो सकते हैं।सी ++ संस्करण

मुझे उत्सुकता है कि सी ++ में इस तरह की स्थिति के लिए संस्करण डेटा स्टोर करने का कोई अच्छा तरीका है। मैं मानक पुस्तकालयों का उपयोग करने के लिए संस्करण के लिए चाहता हूं, इसलिए मैं उपलब्ध COM, Ole, और SQL VARIANT प्रकारों से परहेज कर रहा हूं।

मेरे वर्तमान समाधान इस तरह दिखता है:

enum MetaValueType 
{ 
    MetaChar, 
    MetaString, 
    MetaShort, 
    MetaInt, 
    MetaFloat, 
    MetaDouble 
}; 

union MetaUnion 
{ 
    char cValue; 
    short sValue; 
    int iValue; 
    float fValue; 
    double dValue; 
}; 

class MetaValue 
{ 
... 
private: 
    MetaValueType ValueType; 
    std::string StringValue; 
    MetaUnion VariantValue; 
}; 

MetaValue वर्ग वर्तमान में संग्रहीत संस्करण मूल्य प्राप्त करने के लिए विभिन्न कार्यों जाओ है, लेकिन यह करता है, तो का एक बड़ा ब्लॉक एक मूल्य के लिए, प्रत्येक क्वेरी बनाने समाप्त होता है/अन्यथा यदि बयान यह पता लगाने के लिए कि मैं किस मूल्य की तलाश कर रहा हूं।

मैंने मूल्य को केवल एक स्ट्रिंग के रूप में संग्रहीत करने और अलग-अलग प्रकार के प्रकार प्राप्त करने के लिए रूपांतरण करने का भी पता लगाया है, लेकिन जहां तक ​​मैंने देखा है, यह आंतरिक स्ट्रिंग पार्सिंग और त्रुटि हैंडलिंग का एक समूह है जो ' टी सुंदर, फ्लोटिंग पॉइंट मानों के साथ परिशुद्धता और डेटा हानि के मुद्दों का एक बड़ा पुराना कैन खोलता है, और अगर ऊपर बताई गई समस्या है तो अभी भी क्वेरी को खत्म नहीं करता है।

क्या किसी ने मानक पुस्तकालयों का उपयोग कर सी ++ संस्करण डेटा प्रकार के लिए उपयोग करने के लिए क्लीनर को लागू या देखा है?

+2

मैं एक वर्णनात्मक प्रश्न के रूप में अपने शीर्षक phrasing सुझाव दे सकता है? शायद कुछ "सी ++ में संस्करण डेटा कैसे स्टोर करें?" मुझे लगता है कि आपको और प्रतिक्रिया मिलेगी! – jwfearn

+2

हम्म ... मैं एक बार में शीर्षक समझ गया। –

उत्तर

26

आप Boost.Variant या Boost.Any चाहते हैं।

बस एक अतिरिक्त सूचक के रूप में, आप "प्रकार मिटाएं" देख सकते हैं।

+0

हर्ब सटर इस जवाब को भी सुझाता है: http://herbsutter.com/2008/06/20/type-inference-vs-staticdynamic-typing/ – user79878

8

आप एक और सी-आश समाधान पर भी जा सकते हैं, जिसमें आपके सिस्टम पर एक डबल * आकार का आकार होगा, साथ ही साथ आप किस प्रकार का उपयोग कर रहे हैं। यह उचित रूप से साफ है, लेकिन निश्चित रूप से किसी ऐसे व्यक्ति के लिए एक समाधान है जो सिस्टम के कच्चे बाइट्स के साथ पूरी तरह से सहज महसूस करता है।

+1

शून्य * बहुत बुरा है। जब संभव हो तो अधिक सुरुचिपूर्ण समाधान पसंद करें। –

+5

यह एक बहुत ही सुरुचिपूर्ण समाधान है ... यदि आप कच्ची मेमोरी के साथ काम कर रहे हैं। –

+5

मैं इस बात से सहमत नहीं हूं कि शून्य पॉइंटर्स सुरुचिपूर्ण हैं। आप टाइप सिस्टम को बाईपास कर रहे हैं, यह कच्चे मेमोरी के साथ काम करने में सहज नहीं है, यह आपके द्वारा संभवतः कंपाइलर से सभी मदद प्राप्त करने का मामला है। – lkristjansen

11

जबकि कोनराड का उत्तर (मौजूदा मानकीकृत समाधान का उपयोग करना) निश्चित रूप से अपने स्वयं के बग-प्रोन संस्करण को लिखना बेहतर है, बूस्ट संस्करण में कुछ ओवरहेड्स हैं, खासकर कॉपी निर्माण और स्मृति में।

एक आम अनुकूलित दृष्टिकोण निम्नलिखित संशोधित फैक्टरी पैटर्न है:

  1. एक सामान्य उद्देश्य यह है कि यह भी ऑब्जेक्ट प्रकार समाहित (या तो एक enum के रूप में), या के लिए एक बेस इंटरफ़ेस बनाएँ 'typeid' का उपयोग कर (बेहतर) ।
  2. अब टेम्पलेट Derived कक्षा का उपयोग करके इंटरफ़ेस को कार्यान्वित करें।
  3. हस्ताक्षर के साथ एक templateized create समारोह के साथ एक कारखाने वर्ग बनाएँ:

template <typename _T> Base * Factory::create();

यह आंतरिक रूप से ढेर पर एक Derived<_T> वस्तु बनाता है, और एक गतिशील डाली सूचक retuns। प्रत्येक वर्ग के लिए इसे विशेषज्ञता दें जिसे आप कार्यान्वित करना चाहते हैं।

अंत में, Variant रैपर को परिभाषित करें जिसमें यह Base * पॉइंटर शामिल है और टेम्पलेट को परिभाषित करता है और फ़ंक्शन सेट करता है। getType(), isEmpty(), असाइनमेंट और समानता ऑपरेटरों आदि जैसे उपयोगिता कार्यों को उचित रूप से यहां लागू किया जा सकता है।

उपयोगिता कार्यों और कारखाने के कार्यान्वयन के आधार पर, समर्थित वर्गों को असाइनमेंट या कॉपी निर्माण जैसे कुछ बुनियादी कार्यों का समर्थन करने की आवश्यकता होगी।

+0

फिर, यदि आप कर सकते हैं, तो कृपया बूस्ट क्लास का उपयोग करें, जब तक कि माइक्रोसॉन्ड-स्तरीय समय आपके लिए महत्वपूर्ण न हो। – Fox

+0

फीफा: नैनोसेकंद-स्तर। –

+2

:) प्रति एपीआई उपयोग के लिए नैनोसेकंड - मेरे अनुभव में, इस तरह एक मौलिक कार्यान्वयन जोड़ता है। – Fox

3

हालांकि प्रश्न का उत्तर लंबे समय से दिया गया था, रिकॉर्ड के लिए मैं यह उल्लेख करना चाहता हूं कि QVariant यह भी करता है।

5

सी ++ 17 में अब std::variant है जो आप खोज रहे हैं।

std::variant

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