2009-12-05 10 views
6

अगर मैं सही ढंग से समझता हूं तो हमारे पास संरचना को कार्यान्वित करने के कम से कम दो अलग-अलग तरीके हैं। (स्मार्ट संकेत के साथ कार्यान्वयन के मामले सादगी के लिए बाहर रखा गया है मैं लगभग एसटीएल का उपयोग नहीं करते और यह जानने के लिए कोई इच्छा है।।)सी ++ में कक्षा संरचना को कैसे कार्यान्वित करें?

के विकिपीडिया example पर एक नजर है:

class Car 
{ 
    private: 
    Carburetor* itsCarb; 
    public: 
    Car() {itsCarb=new Carburetor();} 
    virtual ~Car() {delete itsCarb;} 
}; 

तो, यह एक तरीका है - हमारे पास सूचक है जो को निजी सदस्य के रूप में ऑब्जेक्ट करने के लिए है। एक यह पुनर्लेखन कर सकते हैं इस तरह देखने के लिए:

class Car 
{ 
    private: 
    Carburetor itsCarb; 
}; 

उस मामले में हम एक वस्तु ही निजी सदस्य के रूप में की है। (वैसे, क्या मैं इस इकाई को शब्दावली बिंदु से ऑब्जेक्ट को कॉल करने का अधिकार हूं?)

दूसरे मामले में डिफ़ॉल्ट रूप से डिफ़ॉल्ट कन्स्ट्रक्टर को कॉल करने के लिए अनिवार्य नहीं है (यदि किसी को गैर-डिफ़ॉल्ट कन्स्ट्रक्टर को कॉल करने की आवश्यकता है प्रारंभकर्ता सूची में ऐसा करना संभव है) और विनाशक। लेकिन यह एक बड़ी समस्या नहीं है ...

और निश्चित रूप से कुछ पहलुओं में इन दोनों मामलों में अधिक सराहना होती है। उदाहरण के लिए, दूसरे मामले में कार वर्ग के कॉन्स विधियों से कार्बोरेटर उदाहरण के गैर-कॉन्स विधियों को कॉल करने के लिए मना किया गया है ...

क्या कोई निर्णय लेने के लिए कोई "नियम" है? क्या मैं कुछ भूल रहा हूँ?

+1

मुझे लगता है कि आपका मतलब है "कार श्रेणी के कॉन्स विधियों से कार्बोरेटर उदाहरण के गैर-कॉन्स्ट तरीकों को कॉल करना प्रतिबंधित है"। –

+0

@ लॉरेंस ओउप्स। आप निश्चित रूप से सही हैं ... – Wildcat

+8

"[मुझे] [एसटीएल] सीखने की कोई इच्छा नहीं है।" क्या? एसटीएल को अनदेखा करके आप सी ++ का एक बड़ा हिस्सा गायब हैं। – rlbond

उत्तर

7

उस स्थिति में हमारे पास एक निजी सदस्य के रूप में एक वस्तु है। (वैसे, इस इकाई को ऑब्जेक्ट के रूप में कॉल करना क्या मैं शब्दावली बिंदु से लिखता हूं?)

हाँ आप कक्षा का "ऑब्जेक्ट" या "एक उदाहरण" कह सकते हैं।

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

क्या कोई निर्णय लेने के लिए कोई "नियम" है? क्या मुझे कुछ याद आया?

यदि उदाहरण एक से अधिक कंटेनर द्वारा साझा किया जाता है, तो प्रत्येक कंटेनर को इसे मूल्य के बजाय पॉइंटर द्वारा शामिल करना चाहिए; उदाहरण के लिए यदि किसी कर्मचारी के पास बॉस उदाहरण है, तो बॉस द्वारा बॉस को शामिल करें यदि कई कर्मचारी उदाहरण एक ही बॉस साझा करते हैं।

यदि डेटा सदस्य का जीवनकाल कंटेनर के जीवनकाल के समान नहीं है, तो इसे सूचक द्वारा शामिल करें: उदाहरण के लिए यदि कंटेनर के बाद डेटा सदस्य को तुरंत चालू किया गया है, या कंटेनर से पहले नष्ट किया गया है, या नष्ट हो गया है- और कंटेनर के जीवनकाल के दौरान पुनर्निर्मित, या यदि डेटा आंकड़े के लिए यह कभी भी समझ में आता है।

एक और बार जब आपको मूल्य के बजाय पॉइंटर (या संदर्भ द्वारा) शामिल करना होगा, तो डेटा सदस्य का प्रकार एक सार आधार वर्ग होता है।

पॉइंटर द्वारा शामिल करने का एक अन्य कारण यह है कि यह आपको कंटेनर को दोबारा बिना डेटा सदस्य के कार्यान्वयन को बदलने की अनुमति दे सकता है। उदाहरण के लिए, यदि कार और कार्बोरेटर को दो अलग-अलग डीएलएल में परिभाषित किया गया था, तो आप पॉइंटर द्वारा कार्बोरेटर को शामिल करना चाहेंगे: क्योंकि आप Car.dll के पुनर्निर्माण के बिना, अलग-अलग Carburetor.dll इंस्टॉल करके कार्बोरेटर के कार्यान्वयन को बदलने में सक्षम हो सकते हैं।

+0

+1 जैसा कि उन्हें अब तक अनदेखा किया गया प्रतीत होता है – Glen

3

संरचना: जब संभव हो तो सदस्य को प्राथमिकता दें। पॉलीमोर्फिज्म की आवश्यकता होने पर या अग्रेषित घोषणा का उपयोग होने पर पॉइंटर का उपयोग करें। बेशक, स्मार्ट पॉइंटर के बिना, पॉइंटर्स का उपयोग करते समय मैन्युअल मेमोरी प्रबंधन की आवश्यकता होती है।

1

यदि कार्ब के पास कार के समान जीवनकाल है, तो मेरी राय में गैर-सूचक फॉर्म बेहतर है। यदि आपको कार में कार्ब को प्रतिस्थापित करना है, तो मैं सूचक संस्करण का चयन करूंगा।

8

मुझे पहला मामला पसंद है क्योंकि दूसरा व्यक्ति आपको Car.hurettor.h को Car.h में शामिल करने की आवश्यकता है। चूंकि कार्बोरेटोर एक निजी सदस्य है, इसलिए आपको वास्तविक कार कार्यान्वयन कोड की तुलना में कहीं और परिभाषा शामिल नहीं करनी चाहिए। कार्बोरेटोर क्लास का उपयोग स्पष्ट रूप से एक कार्यान्वयन विवरण है और बाहरी ऑब्जेक्ट्स जो आपकी कार ऑब्जेक्ट का उपयोग करती हैं उन्हें अन्य गैर अनिवार्य निर्भरताओं सहित चिंता करने की ज़रूरत नहीं है। एक सूचक का उपयोग करके आपको कार.h में Carburettor की अग्रेषित घोषणा का उपयोग करने की आवश्यकता है।

+0

यह दोनों मामलों में समान है, इसलिए मैंने इसे घटा दिया। –

+0

क्या आप अधिक विशिष्ट हो सकते हैं, मुझे यकीन है कि आपको मेरा अंक नहीं मिला ... – nico

+2

यह दोनों मामलों में _not_ समान नहीं है। जैसा कि निकोलस्कॉर्मियर ने इंगित किया है, आप हेडर फ़ाइल को शामिल करने से बचने के लिए आगे की घोषणा का उपयोग कर सकते हैं। हो सकता है कि आपको डाउनवॉटिंग से पहले जवाब समझना चाहिए। संदर्भों का उल्लेख करने के लिए –

0

आम तौर पर, गैर-पॉइंटर संस्करण का उपयोग करना और बनाए रखना आसान है।

लेकिन कुछ मामलों में, आप इसका उपयोग नहीं कर सकते हैं। उदाहरण के लिए यदि कार में कई कार्बोरेटर हैं और आप उन्हें एक सरणी में रखना चाहते हैं, और कार्बोरेटर कन्स्ट्रक्टर को एक तर्क की आवश्यकता है: आपको उन्हें नए के माध्यम से बनाना होगा और इस प्रकार उन्हें पॉइंटर्स के रूप में स्टोर करना होगा।

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