मुझे C ++ में नए कीवर्ड का उपयोग कब करना चाहिए?


272

मैं थोड़ी देर के लिए C ++ का उपयोग कर रहा हूं, और मैं नए कीवर्ड के बारे में सोच रहा हूं । बस, क्या मुझे इसका उपयोग करना चाहिए, या नहीं?

1) नए कीवर्ड के साथ ...

MyClass* myClass = new MyClass();
myClass->MyField = "Hello world!";

2) नए कीवर्ड के बिना ...

MyClass myClass;
myClass.MyField = "Hello world!";

कार्यान्वयन के दृष्टिकोण से, वे ऐसा प्रतीत नहीं करते हैं कि अलग (लेकिन मुझे यकीन है कि वे हैं) ... हालांकि, मेरी प्राथमिक भाषा सी # है, और निश्चित रूप से पहली विधि वह है जिसका मैं उपयोग कर रहा हूं।

ऐसा लगता है कि विधि 1 को std C ++ कक्षाओं के साथ उपयोग करना कठिन है।

मुझे किस विधि का उपयोग करना चाहिए?

अपडेट 1:

मैंने हाल ही में एक बड़े सरणी के लिए ढेर मेमोरी (या मुफ्त स्टोर ) के लिए नए कीवर्ड का उपयोग किया था जो कि दायरे से बाहर जा रहा था (यानी एक फ़ंक्शन से वापस लौटाया जा रहा था)। जहां पहले मैं स्टैक का उपयोग कर रहा था, जिसके कारण आधे तत्व दायरे से बाहर भ्रष्ट हो गए थे, ढेर उपयोग पर स्विच करने से यह सुनिश्चित हो गया कि तत्व चातुर्य में थे। वाह!

अपडेट 2:

मेरे एक दोस्त ने हाल ही में मुझे बताया कि newकीवर्ड का उपयोग करने के लिए एक सरल नियम है ; हर बार जब आप टाइप करें new, टाइप करें delete

Foobar *foobar = new Foobar();
delete foobar; // TODO: Move this to the right place.

यह मेमोरी लीक को रोकने में मदद करता है, क्योंकि आपको हमेशा डिलीट को कहीं न कहीं रखना होता है (यानी जब आप इसे काटते हैं और इसे या तो विनाशकारी या अन्यथा पेस्ट करते हैं)।


6
संक्षिप्त उत्तर है, छोटे संस्करण का उपयोग करें जब आप इसके साथ भाग सकते हैं। :)
जलफ

11
हमेशा एक समान डिलीट लिखने की तुलना में एक बेहतर तकनीक - जैसे एसटीएल कंटेनर और स्मार्ट पॉइंटर्स का उपयोग करें std::vectorऔर std::shared_ptr। ये आपके लिए newऔर आपके deleteलिए कॉल को लपेटते हैं, इसलिए आपको मेमोरी लीक होने की संभावना भी कम होती है। अपने आप से पूछें, उदाहरण के लिए: क्या आपको हमेशा याद रखना चाहिए कि deleteहर जगह एक अपवाद को रखा जा सकता है? deleteहाथ में डालने से कठिन है जितना आप सोच सकते हैं।
AshleysBrain

पुन :: अद्यतन 1 - सी + + के बारे में सुंदर चीजों में से एक यह है कि यह आपको ढेर पर उपयोगकर्ता परिभाषित प्रकारों को संग्रहीत करने की अनुमति देता है, जबकि कचरा एकत्रित सी # की तरह आप ढेर पर डेटा संग्रहीत करने के लिए मजबूर करते हैं । ढेर खपत स्टैक पर डेटा भंडारण की तुलना में अधिक संसाधनों पर डेटा संग्रहीत करने , इस प्रकार आप को प्राथमिकता देनी चाहिए ढेर करने के लिए ढेर , को छोड़कर जब अपने UDT अपने डाटा स्टोर करने की स्मृति की एक बड़ी राशि की आवश्यकता है। (इसका मतलब यह भी है कि ऑब्जेक्ट डिफ़ॉल्ट रूप से मूल्य से पारित हो जाते हैं)। आपकी समस्या का एक बेहतर समाधान संदर्भ द्वारा फ़ंक्शन को सरणी में पारित करना होगा ।
चार्ल्स अदीस

जवाबों:


303

विधि 1 (उपयोग करके new)

  • फ्री स्टोर पर ऑब्जेक्ट के लिए मेमोरी आवंटित करता है (यह अक्सर ढेर के समान होता है )
  • आपको deleteबाद में स्पष्ट रूप से अपनी वस्तु की आवश्यकता है। (यदि आप इसे नहीं हटाते हैं, तो आप मेमोरी रिसाव बना सकते हैं)
  • मेमोरी तब तक आबंटित रहती है, जब तक आप deleteइसे आवंटित नहीं करते । (अर्थात आप किसी returnऐसी वस्तु को बना सकते हैं जिसे आपने बनाया है new)
  • प्रश्न में उदाहरण तब तक मेमोरी को लीक करेगा जब तक कि पॉइंटर deleteघ न हो; और इसे हमेशा हटा दिया जाना चाहिए , चाहे जिस पर नियंत्रण पथ लिया गया हो, या यदि अपवाद फेंका गया हो।

विधि 2 (उपयोग नहीं new)

  • स्टैक पर ऑब्जेक्ट के लिए मेमोरी आवंटित करता है (जहां सभी स्थानीय चर जाते हैं) स्टैक के लिए आम तौर पर कम मेमोरी उपलब्ध है; यदि आप बहुत अधिक वस्तुओं का आवंटन करते हैं, तो आप स्टैक ओवरफ्लो का जोखिम उठाते हैं।
  • आपको deleteबाद में इसकी आवश्यकता नहीं होगी ।
  • जब यह दायरे से बाहर हो जाता है तो मेमोरी आवंटित नहीं की जाती है। (यानी आपको returnस्टैक पर किसी ऑब्जेक्ट को पॉइंटर नहीं करना चाहिए )

जहां तक ​​उपयोग करने के लिए; आप उस विधि को चुनते हैं जो आपके लिए सबसे अच्छा काम करती है, उपरोक्त बाधाओं को देखते हुए।

कुछ आसान मामले:

  • यदि आप कॉल करने के बारे में चिंता नहीं करना चाहते हैं delete, (और मेमोरी लीक होने की संभावना है ) तो आपको उपयोग नहीं करना चाहिए new
  • यदि आप किसी फ़ंक्शन से किसी ऑब्जेक्ट को पॉइंटर लौटना चाहते हैं, तो आपको इसका उपयोग करना होगा new

4
एक नाइटपिक - मेरा मानना ​​है कि नया ऑपरेटर "फ्री स्टोर" से मेमोरी आवंटित करता है, जबकि मॉलोक "हीप" से आवंटित करता है। ये समान होने की गारंटी नहीं है, हालांकि व्यवहार में वे आमतौर पर हैं। Gotw.ca/gotw/009.htm देखें ।
फ्रेड लार्सन

4
मुझे लगता है कि आपका उत्तर स्पष्ट हो सकता है जिस पर उपयोग करना है। (समय का 99%, चुनाव सरल है। विधि 2 का उपयोग करें, एक आवरण वस्तु पर जो निर्माणकर्ता / विध्वंसक में नया / हटाता है)
jalf

4
@jalf: मेथड 2 वह है जो नए का उपयोग नहीं करता है: - / / किसी भी मामले में, कई बार ऐसा होता है कि आप कोड 2 (नए के बिना एक) का उपयोग करते हुए बहुत सरल हो जाएंगे (जैसे त्रुटि मामलों को संभालना)
डैनियल लेचेमिनेंट 1

एक और नाइटपिक ... आपको यह अधिक स्पष्ट करना चाहिए कि निक का पहला उदाहरण स्मृति को लीक करता है, जबकि उनका दूसरा भी अपवादों का सामना नहीं करता है।
अरफांगियन

4
@Fred, Arafangion: आपकी जानकारी के लिए धन्यवाद; मैंने आपकी टिप्पणियों को उत्तर में शामिल कर लिया है।
डैनियल लेकेमिंटेंट

118

दोनों के बीच एक महत्वपूर्ण अंतर है।

newसी # में मूल्य प्रकारों के साथ बहुत अधिक व्यवहार नहीं किया गया है, और लोग अक्सर कहते हैं कि उन वस्तुओं को स्टैक पर आवंटित किया जाता है, जो शायद सबसे आम / स्पष्ट मामला है, लेकिन हमेशा सच नहीं है। अधिक सटीक रूप से, उपयोग किए बिना आवंटित वस्तुओं newमें स्वचालित भंडारण होता है। अवधि के साथ आवंटित सब कुछ newढेर पर आवंटित किया गया है, और इसके लिए एक संकेतक लौटाया गया है, बिल्कुल सी # में संदर्भ प्रकारों की तरह।

स्टैक पर आबंटित किसी चीज का एक स्थिर आकार होता है, जिसे संकलन-समय पर निर्धारित किया जाता है (कंपाइलर को स्टैक पॉइंटर को सही ढंग से सेट करना होता है, या यदि ऑब्जेक्ट किसी अन्य वर्ग का सदस्य है, तो उसे उस अन्य वर्ग के आकार को समायोजित करना होगा) । इसीलिए C # में सरणियाँ संदर्भ प्रकार हैं। उन्हें होना चाहिए, क्योंकि संदर्भ प्रकारों के साथ, हम रनटाइम पर तय कर सकते हैं कि कितनी मेमोरी मांगनी है। और यहाँ भी वही लागू होता है। केवल स्थिर आकार (एक आकार जिसे संकलन-समय पर निर्धारित किया जा सकता है) के साथ स्वचालित भंडारण अवधि (स्टैक पर) के साथ आवंटित किया जा सकता है। डायनामिक रूप से आकार के सरणियों को कॉल करके, ढेर पर आवंटित किया जाना है new

(और यह वह जगह है जहाँ C # स्टॉप पर कोई समानता है)

अब, स्टैक पर आवंटित कुछ भी "स्वचालित" भंडारण अवधि है (आप वास्तव में एक चर के रूप में घोषित कर सकते हैं auto, लेकिन यह डिफ़ॉल्ट है यदि कोई अन्य भंडारण प्रकार निर्दिष्ट नहीं किया गया है तो कीवर्ड वास्तव में अभ्यास में उपयोग नहीं किया जाता है, लेकिन यह वह जगह है जहां यह है से आता है)

स्वचालित भंडारण अवधि का अर्थ है कि यह कैसा लगता है, चर की अवधि स्वचालित रूप से नियंत्रित की जाती है। इसके विपरीत, ढेर पर आवंटित कुछ भी आपके द्वारा मैन्युअल रूप से हटा दिया जाना है। यहाँ एक उदाहरण है:

void foo() {
  bar b;
  bar* b2 = new bar();
}

यह फ़ंक्शन तीन मानों को ध्यान में रखते हुए बनाता है:

पंक्ति 1 पर, यह एक चर घोषित करता है bbar स्टैक (स्वचालित अवधि) पर प्रकार का ।

पंक्ति 2 पर, यह स्टैक (स्वचालित अवधि) पर एक barपॉइंटर घोषित करता है b2, और नए को कॉल करता है, barजो ढेर पर एक ऑब्जेक्ट आवंटित करता है । (गतिशील अवधि)

जब फ़ंक्शन वापस आता है, तो निम्न होगा: सबसे पहले, b2दायरे से बाहर चला जाता है (विनाश का क्रम हमेशा निर्माण के आदेश के विपरीत होता है)। लेकिन b2सिर्फ एक सूचक है, इसलिए कुछ भी नहीं होता है, यह जो स्मृति रखता है वह बस मुक्त हो जाता है। और महत्वपूर्ण बात, यह जिस मेमोरी को इंगित करता है (a)bar ढेर पर उदाहरण) को छुआ नहीं है। केवल पॉइंटर को मुक्त किया गया है, क्योंकि केवल पॉइंटर की स्वचालित अवधि थी। दूसरा, bदायरे से बाहर हो जाता है, इसलिए चूंकि इसकी स्वचालित अवधि होती है, इसके विध्वंसक को कहा जाता है, और मेमोरी को मुक्त कर दिया जाता है।

और यह bar ढेर पर उदाहरण? यह शायद अभी भी वहाँ है। किसी ने इसे हटाने की जहमत नहीं उठाई, इसलिए हमने मेमोरी लीक कर दी है।

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

और यह बहुत अधिक सटीक है कि अधिकांश C ++ कोड कैसे काम करता है। मानक पुस्तकालय को देखेंstd::vectorउदाहरण लिए देखें। यह आमतौर पर स्टैक पर आवंटित किया जाता है, लेकिन गतिशील रूप से आकार और आकार बदल सकता है। और यह आवश्यक रूप से ढेर पर मेमोरी को आंतरिक रूप से आवंटित करके करता है। कक्षा का उपयोगकर्ता इसे कभी नहीं देखता है, इसलिए मेमोरी लीक करने का कोई मौका नहीं है, या जो आपने आवंटित किया है उसे साफ करना भूल गया है।

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

एक सामान्य नियम के रूप में, अपने उच्च स्तरीय कोड से सीधे नए / डिलीट का उपयोग कभी न करें। इसे हमेशा उस वर्ग में लपेटें जो आपके लिए मेमोरी का प्रबंधन कर सकता है, और जो यह सुनिश्चित करेगा कि यह फिर से मुक्त हो जाए। (हां, इस नियम के अपवाद हो सकते हैं। विशेष रूप से, स्मार्ट पॉइंटर्स के लिए आपको newसीधे कॉल करने की आवश्यकता होती है , और पॉइंटर को इसके निर्माता को पास करना होता है, जो तब संभालता है और सुनिश्चित करता है deleteकि इसे सही ढंग से कहा जाता है। लेकिन यह अभी भी अंगूठे का एक बहुत ही महत्वपूर्ण नियम है। )


2
"नए के साथ आवंटित नहीं किया गया सब कुछ स्टैक पर रखा गया है" उन प्रणालियों में नहीं, जिन पर मैंने काम किया है ... आमतौर पर intialized (और uninit।) वैश्विक (स्थिर) डेटा को अपने स्वयं के खंडों में रखा जाता है। उदाहरण के लिए, .data, .bs, आदि ... लिंकर खंड। पांडित्य, मुझे पता है ...
दान

बेशक, आप सही कह रहे हैं। मैं वास्तव में स्थैतिक डेटा के बारे में नहीं सोच रहा था। मेरा बुरा जरूर है। :)
जलफ

2
स्टैक पर आबंटित कुछ भी एक स्थिर आकार क्यों है?
user541686

यह हमेशा नहीं होता है , इसे दरकिनार करने के कुछ तरीके हैं, लेकिन सामान्य स्थिति में यह होता है, क्योंकि यह एक स्टैक पर है। यदि यह स्टैक के शीर्ष पर है, तो इसे आकार देना संभव हो सकता है, लेकिन एक बार जब कुछ और इसके ऊपर धकेल दिया जाता है, तो यह "दीवार में", दोनों तरफ की वस्तुओं से घिरा होता है, इसलिए इसे वास्तव में आकार नहीं दिया जा सकता है । हाँ, कह रही है यह हमेशा कि है एक निश्चित आकार एक सरलीकरण का एक सा है, लेकिन यह मूल विचार बता देते हैं (और मैं सी कार्य करता है जो आप ढेर आवंटन के साथ भी रचनात्मक होना जाने के साथ के बारे में खिलवाड़ की सिफारिश नहीं होगा)
jalf

14

मुझे किस विधि का उपयोग करना चाहिए?

यह लगभग आपकी टाइपिंग प्राथमिकताओं से नहीं बल्कि संदर्भ से निर्धारित होता है। यदि आपको वस्तु को कुछ स्टैक के पार रखने की आवश्यकता है या यदि यह ढेर के लिए बहुत भारी है, तो आप इसे मुफ्त स्टोर पर आवंटित करते हैं। इसके अलावा, चूंकि आप एक ऑब्जेक्ट आवंटित कर रहे हैं, आप मेमोरी को रिलीज़ करने के लिए भी जिम्मेदार हैं। लुकअपdelete ऑपरेटर।

फ्री-स्टोर प्रबंधन का उपयोग करने के बोझ को कम करने के लिए लोगों ने सामान का आविष्कार किया है जैसे auto_ptrऔर unique_ptr। मैं आपको दृढ़ता से इन पर एक नज़र डालने की सलाह देता हूं। वे आपके टाइपिंग मुद्दों के लिए भी मदद कर सकते हैं; ;-)


10

यदि आप C ++ में लिख रहे हैं तो आप शायद प्रदर्शन के लिए लिख रहे हैं। स्टैक का उपयोग करने की तुलना में नए और मुफ्त स्टोर का उपयोग करना बहुत धीमा है (विशेष रूप से थ्रेड्स का उपयोग करते समय) तो केवल इसका उपयोग करें जब आपको इसकी आवश्यकता हो।

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

इसके अलावा, कभी भी डिलीट का उपयोग करने से बचने की कोशिश करें। इसके बजाय अपने नए को स्मार्ट पॉइंटर में लपेटें। स्मार्ट पॉइंटर कॉल को अपने लिए डिलीट कर दें।

कुछ ऐसे मामले हैं जहां स्मार्ट पॉइंटर स्मार्ट नहीं है। STL कंटेनर के अंदर कभी भी std :: auto_ptr <> स्टोर न करें। कंटेनर के अंदर कॉपी ऑपरेशंस की वजह से यह बहुत जल्द पॉइंटर को हटा देगा। एक और मामला है जब आपके पास ऑब्जेक्ट्स के लिए वास्तव में बड़े एसटीएल कंटेनर हैं। बढ़ावा :: साझा_प्रति <> गति ओवरहेड का एक टन होगा क्योंकि यह संदर्भ को ऊपर और नीचे गिनता है। उस मामले में जाने का बेहतर तरीका यह है कि एसटीएल कंटेनर को किसी अन्य वस्तु में डाल दिया जाए और उस वस्तु को नष्ट कर दिया जाए जो कंटेनर के प्रत्येक पॉइंटर पर डिलीट कहलाएगी।


10

संक्षिप्त उत्तर है: यदि आप C ++ में शुरुआती हैं, तो आपको कभी भी उपयोग नहीं करना चाहिए newया नहीं करना चाहिएdelete अपने आप को।

इसके बजाय, आप स्मार्ट संकेत का उपयोग करना चाहिए जैसे std::unique_ptrऔर std::make_unique(या कम अक्सर, std::shared_ptrऔर std::make_shared)। इस तरह, आपको मेमोरी लीक के बारे में ज्यादा चिंता करने की जरूरत नहीं है। और यहां तक ​​कि अगर आप अधिक उन्नत हैं, तो सबसे अच्छा अभ्यास आमतौर पर आपके द्वारा उपयोग किए जा रहे कस्टम तरीके newऔर deleteएक छोटे वर्ग (जैसे कि एक कस्टम स्मार्ट पॉइंटर) को एनकैप्सुलेट करने के लिए होगा जो कि ऑब्जेक्ट जीवनचक्र के मुद्दों के लिए समर्पित है।

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


यह देखना दिलचस्प है कि समय बीतने के साथ उत्तर कैसे बदल सकता है?)
वोल्फ


2

सरल उत्तर हां है - नया () ढेर पर एक वस्तु बनाता है (दुर्भाग्यपूर्ण साइड इफेक्ट के साथ जो आपको अपने जीवनकाल का प्रबंधन करना है (स्पष्ट रूप से उस पर डिलीट कॉल करके), जबकि दूसरा रूप वर्तमान में स्टैक में एक ऑब्जेक्ट बनाता है गुंजाइश और उस वस्तु को नष्ट कर दिया जाएगा जब यह दायरे से बाहर चला जाता है।


1

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

उस ने कहा, कुछ स्पष्ट उदाहरण हैं जहां स्टैक चर अपर्याप्त हैं।

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

अन्य, अधिक संभावित स्थिति यह है कि आपके चर को आपके फ़ंक्शन के दायरे से परे "लाइव" करने की आवश्यकता है। इस स्थिति में, आप वेरिएबल को ढेर पर आवंटित करेंगे ताकि किसी दिए गए फ़ंक्शन के दायरे के बाहर पहुंचा जा सके।


1

क्या आप myClass को किसी फ़ंक्शन से पास कर रहे हैं, या उस फ़ंक्शन के बाहर मौजूद होने की अपेक्षा कर रहे हैं? जैसा कि कुछ अन्य लोगों ने कहा, जब आप ढेर पर आवंटित नहीं कर रहे हैं, तो यह गुंजाइश के बारे में है। जब आप फ़ंक्शन को छोड़ते हैं, तो यह चला जाता है (अंततः)। शुरुआती लोगों द्वारा की गई क्लासिक गलतियों में से एक एक समारोह में कुछ वर्ग की एक स्थानीय वस्तु बनाने और इसे ढेर पर आवंटित किए बिना वापस करने का प्रयास है। मुझे याद है कि इस तरह की चीज़ को वापस करने से पहले के दिनों में मैं सी ++ कर रहा था।


0

दूसरी विधि स्टैक पर उदाहरण के साथ-साथ कुछ घोषित की गई चीजों intऔर फ़ंक्शन में पारित होने वाले मापदंडों की सूची के साथ बनाता है ।

पहली विधि स्टैक पर एक पॉइंटर के लिए जगह बनाती है , जिसे आपने मेमोरी में स्थान पर सेट किया है जहां एक नयाMyClass ढेर - या मुफ्त स्टोर पर आवंटित किया गया है।

पहली विधि में यह भी आवश्यक है कि आप deleteजो बनाते हैं new, जबकि दूसरी विधि में, वर्ग स्वचालित रूप से नष्ट हो जाता है और मुक्त हो जाता है जब यह दायरे से बाहर हो जाता है (अगला समापन ब्रेस, आमतौर पर)।


-1

संक्षिप्त उत्तर हां "नया" कीवर्ड अविश्वसनीय रूप से महत्वपूर्ण है जब आप इसका उपयोग करते हैं तो ढेर के विपरीत ऑब्जेक्ट डेटा को ढेर पर संग्रहीत किया जाता है, जो सबसे महत्वपूर्ण है!

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.