2012-07-13 23 views
12

ठीक पर सदस्य चर घोषित करने के लिए कब और क्यों, ठीक है, इसलिए मैं सी ++ प्रोग्रामिंग में बहुत नया हूं, और मैं इसके लिए एक निर्णायक उत्तर के लिए कुछ दिनों के लिए देख रहा हूं। मुझे ढेर बनाम ढेर पर सदस्य चर घोषित करना चाहिए? अधिकांश उत्तरों जो मैंने पाया है, ने अन्य मुद्दों के साथ निपटाया है, लेकिन मैं जानना चाहता हूं कि सदस्य चर के लिए ढेर का उपयोग करना सबसे अच्छा क्यों है और सदस्यों को ढेर करने के बजाय सदस्यों को ढेर करना बेहतर क्यों है।ढेर सी ++

+1

* सदस्य * चर * वर्ग * सदस्यों को संदर्भित करते हैं, और ऐसे में जाते हैं जहां कक्षा का * इंस्टेंस * जाता है। – CapelliC

उत्तर

18

पहले समझ दो महत्वपूर्ण अवधारणाओं रहे हैं:

  1. एक "ढेर" और "ढेर" के मामले में सोच से बचना चाहिए। वे भाषा के नहीं, आपके कंपाइलर/मंच के कार्यान्वयन विवरण हैं। इसके बजाय, ऑब्जेक्ट लाइफटाइम के संदर्भ में सोचें: क्या ऑब्जेक्ट का जीवनकाल उसके "माता-पिता" से मेल खाना चाहिए, या इसे इसे पार करना चाहिए? यदि आपको बाद वाले की आवश्यकता है, तो आपको किसी ऑब्जेक्ट को गतिशील रूप से आवंटित करने के लिए new (प्रत्यक्ष या परोक्ष रूप से) का उपयोग करना होगा।

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

हालांकि, आपके प्रश्न का कोई सामान्य उत्तर नहीं है। गंभीरता से बोलते हुए, गतिशील रूप से आवंटित न करें जब तक कि कोई अच्छा कारण न हो। जैसा कि मैंने उपरोक्त संकेत दिया है, ये कारण आमतौर पर उन स्थितियों से मेल खाते हैं जहां जीवनकाल को अपने "माता-पिता" से अलग होना चाहिए।


1. वास्तव में, सी ++ मानक वास्तव में "ढेर" और "ढेर" के बारे में बात नहीं करता है। अनुकूलन या आम तौर पर प्रदर्शन के बारे में सोचते समय विचार करना महत्वपूर्ण है, लेकिन वे प्रोग्राम-कार्यक्षमता बिंदु दृश्य से अधिकतर अप्रासंगिक हैं।

+0

"आमतौर पर उन स्थितियों से मेल खाता है जहां जीवनकाल को अपने माता-पिता से भिन्न होना चाहिए": क्या हम अभी भी सदस्य के रूप में कुछ बात कर सकते हैं? –

+0

@ जेम्ससांज: दरअसल, मुझे इसे स्पष्ट करना चाहिए। –

+1

ऑब्जेक्ट्स को गतिशील जीवनकाल की आवश्यकता होती है यदि वे गतिशील रूप से आकार में हैं, या ऑब्जेक्ट को वर्चुअल बेस क्लास में कास्टिंग करने के लिए। –

1

स्टैकcall stack को संदर्भित करता है। फ़ंक्शन कॉल, रिटर्न पते, पैरामीटर और स्थानीय चर कॉल कॉल पर रखे जाते हैं। जब भी आप पैरामीटर पास करते हैं या स्थानीय चर बनाते हैं तो आप स्टैक मेमोरी का उपयोग करते हैं। ढेर में केवल अस्थायी भंडारण है। एक बार जब वर्तमान कार्य गुंजाइश से बाहर हो जाता है, तो अब आपके पास पैरामीटर के लिए किसी भी चर के लिए उपयोग नहीं है।

ढेर गतिशील आवंटन के लिए उपयोग की जाने वाली स्मृति का एक बड़ा पूल है। जब आप मेमोरी आवंटित करने के लिए new ऑपरेटर का उपयोग करते हैं, तो यह स्मृति ढेर से असाइन की जाती है। जब आप ऑब्जेक्ट्स बना रहे हैं तो आप ढेर मेमोरी आवंटित करना चाहते हैं, जिसे आप चालू फ़ंक्शन समाप्त होने के बाद खोना नहीं चाहते हैं (गुंजाइश खो देता है)। वस्तुओं को ढेर में तब तक संग्रहीत किया जाता है जब तक कि अंतरिक्ष delete या free() के साथ स्थानांतरित नहीं हो जाता है।

+0

ऑब्जेक्ट्स को गतिशील जीवनकाल की आवश्यकता होती है यदि वे गतिशील रूप से आकार में हैं, या ऑब्जेक्ट को वर्चुअल बेस क्लास में कास्टिंग करने के लिए। –

4

सदस्य चर वर्ग के सदस्य हैं। वे न तो ढेर पर हैं और न ही ढेर पर हैं, या बल्कि वे हैं जहां कभी भी कक्षा है। बहुरूपता (यदि सदस्य के प्रकार हमेशा एक ही नहीं है) तब तक सबसे आम है:

वहाँ अविवेक का एक स्तर जोड़ने के लिए, और ढेर पर अलग से एक सदस्य आवंटित करने के लिए बहुत कुछ कारण हैं।

+0

ऑब्जेक्ट्स को गतिशील जीवनकाल की आवश्यकता होती है यदि वे गतिशील रूप से आकार में हैं, या ऑब्जेक्ट को वर्चुअल बेस क्लास में कास्टिंग करने के लिए। –

+0

@MooingDuck ऑब्जेक्ट्स जो गतिशील रूप से आकार में हैं उन्हें अपनी कक्षा (जैसे 'std :: vector') द्वारा प्रबंधित किया जाना चाहिए: आप सदस्यों के रूप में _them_ आवंटित नहीं करते हैं; आप कंटेनर सदस्य बनाते हैं। और वर्चुअल बेस क्लास को कास्ट करना या जो कुछ भी तात्पर्य है कि सदस्य पॉलिमॉर्फिक है, जिसका मैंने उल्लेख किया है। –

+0

ठीक है, काफी उचित –

2

कुछ शब्दावली सीधे प्राप्त करने के लिए: आप heap और stack ऑब्जेक्ट्स के जीवनकाल का वर्णन करते हैं।पहला मतलब है कि जीवनकाल dynamic है, दूसरा automatic और तीसरा (जिसका आप उल्लेख नहीं करते हैं) static है।

आमतौर पर आपको किसी ऑब्जेक्ट के dynamic जीवनकाल की आवश्यकता होगी, जब इसे उस क्षेत्र में पारित किया जाना चाहिए। एक और आम मामला यह है कि जब आप इसे विभिन्न मूल ऑब्जेक्ट्स में साझा करना चाहते हैं। इसके अलावा, गतिशील जीवनकाल भी आवश्यक है जब आप ऐसे डिज़ाइन के साथ काम करते हैं जो भारी वस्तु-उन्मुख होता है (बहुत सारे बहुरूपता का उपयोग करता है, मानों का उपयोग नहीं करता है), उदा। Qt

एक मुहावरे जिसके लिए गतिशील जीवनकाल की आवश्यकता होती है वह पिंपल-मुहावरे है।

अधिकांश जेनेरिक-प्रोग्रामिंग पुस्तकालय मूल्य और मूल्य-अर्थशास्त्र के प्रति अधिक केंद्रित होते हैं, इसलिए आप गतिशील बाध्यकारी का उपयोग नहीं करेंगे कि अधिक और स्वचालित जीवनकाल बहुत आम हो जाते हैं।

भी कुछ उदाहरण हैं, जहां गतिशील आवंटन अधिक कार्यान्वयन विशिष्ट कारणों के लिए आवश्यक है के होते हैं:

  • गतिशील आकार वस्तुओं (कंटेनर)
  • अधूरा प्रकार से निपटने (देखें pimpl-मुहावरा)
  • की आसान nullability एक प्रकार

ये सभी सामान्य दिशानिर्देश हैं और मामले के आधार पर इसे किसी मामले पर निर्णय लेना होगा। सामान्य रूप से, गतिशील लोगों पर स्वचालित वस्तुओं को प्राथमिकता दें।

0

इस उदाहरण पर विचार करें:

आप एक लिंक्ड सूची लागू करते हैं जिसमें कक्षा नोड का फील्ड सदस्य प्रमुख होता है।
प्रत्येक नोड में फ़ील्ड सदस्य next है। यदि नोड प्रकार और नोड * का यह सदस्य प्रत्येक नोड का आकार श्रृंखला में उसके बाद नोड्स की संख्या पर निर्भर करेगा।

उदाहरण के लिए, यदि आपके पास आपकी सूची में 100 नोड्स हैं तो आपका हेड सदस्य बड़ा होगा। क्योंकि यह अगले नोड को अपने अंदर रखता है, इसलिए इसे पकड़ने के लिए पर्याप्त आकार होना चाहिए और अगला अगला और इसी तरह रखता है। तो सिर में अगले 9 8 नोड्स को पकड़ने के लिए पर्याप्त जगह होनी चाहिए और इस तरह ...

आप इससे बचना चाहते हैं तो इस मामले में प्रत्येक नोड में पॉइंटर को प्रत्येक नोड में रखना बेहतर होगा अगले नोड खुद ही।

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