2010-09-01 12 views
12

मेरी इच्छा है कि मैं वर्चुअल बेस क्लास का ऑब्जेक्ट वापस कर सकता हूं ताकि मुझे मेमोरी मैनेजमेंट से निपटने की आवश्यकता न हो (फ़ंक्शन प्रोग्रामिंग का विचार भी इस प्रयास को उत्तेजित करता है)। इसका मतलब है कि मैं नीचे की तरह कुछ चीजें देख रहा हूँ:हमेशा इंटरफ़ेस डिज़ाइन में कक्षा में एक पॉइंटर वापस करना चाहिए?

class Car 
{ 
    public: 
    virtual int price() = 0 ; 
    virtual string brand() = 0 ; 
} 

class Interface 
{ 
    public: 
    virtual Car giveMeACar() = 0 ; 
    virtual vector<Car> listMeAllTheCars() = 0 ; 
} 

बहरहाल, यह भी कारण है कि कार एक सार इंटरफेस है संकलन नहीं होगा, एक त्रुटि संदेश के साथ:

अमान्य सार वापसी प्रकार सदस्य फ़ंक्शन 'virtual Car giveMeACar() = 0; क्योंकि वर्चुअल फ़ंक्शंस के बाद शुद्ध 'Car' के भीतर हैं: string brand(); स्मार्ट सूचक उपयोग करने का विकल्प को खारिज -

तो, (उपयोग करने के बाद उदाहरण हटाना) का मतलब है कि मैं संशोधित करने के लिए अपने आप को नीचे और प्रबंधक स्मृति की तरह कुछ करने के लिए इंटरफ़ेस है करता है।

class Interface 
{ 
    public: 
    virtual Car* giveMeACar() = 0 ; 
    virtual vector<Car*> listMeAllTheCars() = 0 ; 
} 

मेरे सवाल यह है: यह मेरे पास है ही एकमात्र विकल्प है जब डिजाइन एक अंतरफलक जहां हर चीजों (वर्ग) सार है?

इंटरफ़ेस कक्षा का ऑब्जेक्ट लौटने से जावा में बिल्कुल मान्य है। सी ++ इस पहलू में कूड़े बिट वर्बोज़ और काउंटर सहज ज्ञान प्रतीत होता है। अक्सर, मुझे लगता है कि सी ++ "ऑब्जेक्ट प्रोग्रामिंग भाषा" के बजाय "प्रोग्रामिंग भाषा ऑब्जेक्ट करने के लिए सूचक" है क्योंकि पॉइंटर के बिना आपको ऑब्जेक्ट प्रोग्रामिंग का बहुत अधिक लाभ नहीं मिल सकता है।

+0

+1 वर्चुअल फ़ंक्शंस बनाने के लिए निजी: – Chubsdad

+1

@chubsdad: क्यों? यह मेरा इरादा नहीं है..मुझे सार्वजनिक – pierrotlefou

+1

-1 का उपयोग करना चाहिए था, तो गैर वर्चुअल इंटरफेस मुहावरे देखें। उदाहरण के लिए, यदि सार्वजनिक विधियां वर्चुअल हैं तो आप अपने इंटरफ़ेस की सीमाओं पर इनवेरिएंट को लागू नहीं कर सकते हैं। –

उत्तर

7

जावा में, "लौटने और ऑब्जेक्ट" वास्तव में सी ++ में ऑब्जेक्ट में पॉइंटर लौटने के बराबर समान रूप से समकक्ष है, आप किसी वस्तु को मूल्य से वापस करने की कोशिश कर रहे हैं, जो इसकी एक प्रति बनाता है। आप एक अमूर्त वस्तु की एक प्रति नहीं बना सकते हैं।

तो, सी ++ अधिक वर्बोज़ हो सकता है, यह पैरामीटर प्रदान करने और मूल्यों लौटने के लिए अलग अलग अर्थ विज्ञान जो जावा (मूल्य से वापसी, संदर्भ द्वारा पारित) का समर्थन नहीं करता समर्थन करता है,।

इसके साथ ही कहा, आप स्मार्ट सूचक है, जो आप के लिए स्मृति प्रबंधन करता है के द्वारा लौटना चाहिए। अन्य लोग बाहर स्वामित्व हस्तांतरण अर्थ विज्ञान के साथ auto_ptr बताया है, लेकिन आप यह भी boost::shared_ptr उपयोग कर सकते हैं, मामले में आप कस्टम स्मृति आवंटन आंतरिक रूप से उपयोग करें (उदाहरण के लिए एक पूल), shared_ptr के कस्टम Deleter सुविधा आपको इंटरफेस के उपयोगकर्ता से आवंटन रद्द करने के विवरण को छिपाना में मदद मिलेगी। इसका उपयोग एसटीएल कंटेनरों में भी किया जा सकता है (auto_ptr के विपरीत)।

class Car 
{ 
public: 
    typedef boost::shared_ptr<Car> Ptr; 
    virtual int price() = 0 ; 
    virtual string brand() = 0 ; 
}; 

class Interface 
{ 
public: 
    virtual Car::Ptr giveMeACar() = 0 ; 
    virtual vector<Car::Ptr> listMeAllTheCars() = 0 ; 
} 
+0

मुझे बढ़ावा देने के बाद वाक्यविन्यास पसंद है। हालांकि, एक एम्बेडेड प्रोजेक्ट के लिए, बूस्ट और अप्रत्याशित समस्या को संकलित करने के क्रॉस का कार्य हमेशा मुझे इसका उपयोग करने से दूर रखता है ... – pierrotlefou

+0

@pierr, हाँ बूस्ट एक सुअर का थोड़ा सा है, लेकिन 'shared_ptr' परेशानी हेडर-केवल कार्यान्वयन , आपको किसी भी बढ़ावा पुस्तकालयों से लिंक करने की आवश्यकता नहीं है। आप यह भी जांच सकते हैं कि आपका कंपाइलर 'std :: tr1 :: shared_ptr' (फीचर पैक के साथ जीसीसी 4+, एमएसवीसी 2008) का समर्थन करता है, तो आपको बिल्कुल बढ़ावा की आवश्यकता नहीं है। –

+0

सौभाग्य से, मेरा क्रॉस कंपाइलर समर्थन std :: tr1 :: shared_ptr – pierrotlefou

1

मुझे लगता है कि this उपयोग का हो सकता है।

+2

पेज पढ़ने लोगों के लिए, यह अच्छा है कि कुछ संकेत जहां लिंक ओर जाता है ... –

4

आपके अवलोकन सही हैं, आप जो करना चाहते हैं उसे करने का कोई आसान तरीका नहीं है। सी ++ में आप मूल्य से कार वापस नहीं कर सकते हैं क्योंकि (अन्य चीजों के साथ) कॉलर को इसके लिए स्थान आवंटित करने की आवश्यकता होती है।

जावा मूल रूप से अलग नहीं है, यह सिर्फ इतना है कि इसका वाक्यविन्यास जो आप व्यक्त करना चाहते हैं उसे व्यक्त नहीं कर सकता - सभी प्रकार (आदिम प्रकारों को छोड़कर) उनके पास एक अंतर्निहित '*' है। और इसमें कचरा संग्रह है, इसलिए आपको स्मृति प्रबंधन के बारे में चिंता करने की आवश्यकता नहीं है।

template<class CarClass> 
class Interface { 
    virtual CarClass giveMeACar() = 0; 
    virtual vector<CarClass> listMeAllTheCars() = 0; 
} 
+0

क्या आपका मतलब "अपने वाक्य रचना व्यक्त कर सकते हैं कि आप क्या व्यक्त करना चाहता हूँ" है तो क्या होगा? – pierrotlefou

+2

नहीं, मेरा मतलब था "नहीं कर सकता"। जावा मूल्य के आधार पर कक्षा को वापस करने का कार्य व्यक्त नहीं कर सकता है। सभी वर्गों को संदर्भ द्वारा स्पष्ट रूप से पारित किया जाता है। शायद निकटतम जावा "कार x = giveMeacar();" सी ++ में "कार एक्स = (कार) दें मेकर() क्लोन();" (यदि कार क्लोन विधि को सही ढंग से लागू करती है)। –

+0

मैं उलझन में हूँ। जावा हमेशा मूल्य से गुजरना चाहिए। http://stackoverflow.com/questions/40480/is-java-pass-by-reference – pierrotlefou

2

अन्य विकल्प के लिए एक टेम्पलेट का उपयोग करने के लिए है। यह वस्तु को पॉइंटर की तरह ढेर पर रखता है, लेकिन जब यह एक स्टैक वैरिएबल की तरह गुंजाइश से बाहर हो जाता है तो इसे हटा देता है।

भिन्नताओं में boost::unique_ptr और सी ++ 0x std::unique_ptr शामिल हैं, जो auto_ptr से अधिक है।

vector<Car>vector< auto_ptr<Car> > द्वारा प्रतिस्थापित नहीं किया जा सकता है क्योंकि auto_ptr कंटेनरों के साथ असंगत है। इसके लिए आपको unique_ptr का उपयोग करने की आवश्यकता है।

3

वापसी एक std::auto_ptr<Car>:

+0

और इन पॉइंटर प्रकारों (यदि बाद में प्रदर्शन आदि के लिए जरूरी है) के बीच स्विच करने के लिए सुसंगतता, टाइपिबिलिटी और रखरखाव का एक बिंदु, तो आप एक टाइपपीफ बनाना चाहेंगे। यह एक बहुत आम दृष्टिकोण है। –

+1

[बधाई हो!] (Http://stackoverflow.com/badges/49/c?userid=153285) –

0

आपकी क्वेरी के जवाब में अन्य पोस्ट पूरी तरह से आपकी क्वेरी का उत्तर दें।

बचें बाहरी दुनिया के कार्यान्वयन के बारे में जानकारी को उजागर: हालांकि, मैं बस कुछ टिप्पणियों जो आप विचार कर सकते हैं

पहले अवलोकन किया था।

यह

virtual vector<Car> listMeAllTheCars() = 0 ; की वापसी प्रकार के संबंध में है।

कक्षा के उपयोगकर्ताओं को पता होना चाहिए कि क्या आप vector या list या कुछ और उपयोग कर रहे हैं? जीओएफ से इटरेटर डिजाइन पैटर्न देखें। सी ++ के इटरेटर के लिए अच्छा समर्थन है।

दूसरा अवलोकन:

आपका आवश्यकता फैक्टरी विधि डिजाइन पैटर्न के लिए जरूरत की नकल करने लगता है, खासकर जब मैं

virtual Car giveMeACar() = 0 ;

को देखो आप फैक्टरी विधि डिजाइन पैटर्न को देखने के लिए चाहते हो सकता है

तीसरा अवलोकन:

हालांकि इन दोनों मज़े की उपस्थिति एक इंटरफ़ेस में ctions, मुझे जगह से थोड़ा कम दिखता है। आप फिर से डिजाइन पर विचार करना चाह सकते हैं। Single Responsibility Principle.

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

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