2010-12-31 19 views
9

में जेनेरिक कंटेनर मैं एक सामान्य कंटेनर प्रकार बनाने का प्रयास कर रहा हूं ताकि एक सामान्य इंटरफ़ेस प्रदान किया जा सके, साथ ही उन आंतरिक कंटेनरों को छुपाएं जिन्हें मैं बदल रहा हूं क्योंकि वे परिवर्तन के अधीन हैं।सी ++

असल में मेरे पास प्लगइन हैं जो आइटमों का संग्रह वापस करते हैं और मैं नहीं चाहता कि प्लगइन्स मेरे कोड का उपयोग कर रहे कंटेनर के प्रकार से अवगत रहें।

क्या कोई मुझे बेहतर दिशा में इंगित कर सकता है तो नीचे उदाहरण कोड?

template<class C, typename I> 
class Container 
{ 
public: 
//... 

    void push(const I& item) 
    { 
     if(typeid(C) == typeid(std::priority_queue<I>)) 
     { 
      std::priority_queue<I>* container = (std::priority_queue<I>*)&_container; 
      container->push(item); 
     } 
     if(typeid(C) == typeid(std::list<I>)) 
     { 
      std::list<I>* container = (std::list<I>*)&_container; 
      container->push_back(item); 
     } 
     else 
     { 
      //error! 
     } 
    }; 

    private: 
    C _container; 
//... 
} 

धन्यवाद

+4

मैं कर सकता हूं। ऐसा मत करो। अपना ऐप डिज़ाइन करने पर अपना समय व्यतीत करें ताकि यह स्थिर रूप से टाइप किए गए कंटेनर का उपयोग कर सके। – ybungalobill

+1

मैं आपको एक बेहतर दिशा में इंगित कर सकता हूं, सुनिश्चित करें: ** ऐसा करने का प्रयास न करें **। गंभीरता से। यह आपको कुछ भी हासिल नहीं करेगा। अनुभव की आवाज़ यहाँ बोल रही है। –

+6

यहां डाउनवोट क्यों है? यह एक बिल्कुल वैध सवाल है। भले ही जवाब "इस तरह से मत करो", यह अभी भी एक वैध सवाल था। – Tim

उत्तर

6

मेरे पास प्लगइन हैं जो आइटमों का संग्रह वापस करते हैं और मैं नहीं चाहता कि प्लगइन्स मेरे कोड का उपयोग कर रहे कंटेनर के प्रकार से अवगत रहें।

अपने प्लग-इन वस्तुओं के अपने संग्रह में begin और end iterators प्रदान करते हैं और उसके बाद सीमा का उपभोग आप मनचाहे ढंग से है।

इटरेटर्स का सबसे बड़ा लाभ यह है कि डेटा को कैसे उपयोग किया जाता है (एल्गोरिदम) आपके डेटा में, प्लगइन डेटा का उपभोग करने वाले आपके एप्लिकेशन कोड से डेटा को संग्रहीत (कंटेनर) के पूर्ण decoupling की अनुमति देता है।

इस तरह, आपको यह ध्यान रखना नहीं है कि प्लगइन्स अपने डेटा को कैसे स्टोर करते हैं और प्लगइन्स को आपके डेटा के साथ आपके द्वारा किए जाने वाले कार्यों की परवाह नहीं है।

+0

आपके उत्तरों जेम्स के लिए धन्यवाद। दृश्य पर धागे दिखाई देने पर इस दृष्टिकोण को बालों में बदल दिया गया था। उदाहरण के लिए एक डेटास्टोर प्लगइन में get_events (int validator_id) विधि हो सकती है जिसे अलग-अलग मान्यक आईडी के साथ एकाधिक थ्रेड द्वारा बुलाया जा सकता है। – Corvusoft

+2

@user: मुझे समझ में नहीं आता; एक इटरेटर इंटरफ़ेस में एक कंटेनर इंटरफ़ेस की तुलना में कोई और सहमति नहीं है: या तो कंटेनर को लॉक करते समय आप इसे फिर से चालू कर रहे हैं या कंटेनर की एक प्रतिलिपि बनाने के लिए बनाते हैं। –

+0

+1। लेकिन मुझे लगता है कि प्लगइन के रिटर्न वैल्यू का उपभोग करने वाले कोड को फिर से कंपाइल करने की आवश्यकता से बचने के लिए वांछनीय होगा यदि सड़क पर एक नई प्लगइन बनाया गया है जो आंतरिक कंटेनर प्रकार का आंतरिक रूप से उपयोग करता है - किस मामले में, कैसे? ऐसा लगता है कि आपको 'स्टार्ट()' और 'एंड()' बेस क्लासेस (इंटरफेस) द्वारा अपने दाहिनी ओर इटेटरेटर्स लौटाएंगे, और उन्हें शुद्ध आभासी 'ऑपरेटर ++() 'और' ऑपरेटर *()' आदि विधियों; फिर प्रत्येक कंटेनर प्रकार का उपयोग करने के लिए, एक ठोस उपclass बनाएं जो कि सही प्रकार के इटरेटर के लिए इसी विधि के लिए आगे है, है ना? मुश्किल लगता है ... –

0

तुम्हें पता है, जब आप "आम इंटरफेस" लिखा था, मुझे यकीन है कि आप एक अमूर्त वर्ग और उपवर्गों कि मानक कंटेनर लपेट के साथ कुछ जावा शैली को दिखाने के लिए जा रहे थे था। मैं टाइपिड कॉल का एक गुच्छा देखने के लिए आश्चर्यचकित था ...

लेकिन फिर, आप ऐसा क्यों करना चाहते हैं? अधिकांश कंटेनर एक आम इंटरफ़ेस साझा करते हैं, और SFINAE की शक्ति के साथ, आपको विशेष कोड भी लिखना नहीं पड़ता है! बस टेम्पलेट का उपयोग करें और विधि को सीधे कॉल करें।

संपादित करें: भूल गए कि मानक कंटेनर के पास कोई वर्चुअल तरीका नहीं है और इसलिए dynamic_cast एड नहीं हो सकता है।

0

उपरोक्त के रूप में कक्षा के साथ शुरू करें, अपने प्लगइन द्वारा आवश्यक न्यूनतम इंटरफ़ेस का पर्दाफाश करें। फिर उस कंटेनर के संदर्भ में इसे लागू करें जिसका आप उपयोग करने जा रहे हैं। इसे कंटेनर एडेप्टर कहा जाता है और यह है कि std :: स्टैक कैसे कार्यान्वित किया जाता है।

यदि आपको वास्तव में अधिक के लिए एडाप्टर की आवश्यकता है तो एक एसटीएल कंटेनर टेम्पलेट के साथ जाएं, std :: stack पर एक नज़र डालें, यह दिखाएगा कि यह कैसे करें।

टाइपिड पर स्विच न करें, आप इसे क्यों चाहेंगे?

बीटीडब्लू, जो जेम्स सुझाव देता है उसके साथ जाएं जब तक कंटेनर का पर्दाफाश करने की आवश्यकता न हो।