2009-02-27 15 views
9

क्या यह स्पष्ट रूप से ढेर पर (नए के माध्यम से) ऑब्जेक्ट सदस्यों को रखने के लिए बुरी आदत/बुरी आदत माना जाता है? मुझे लगता है कि आप क्लाइंट को ऑब्जेक्ट को तुरंत चालू करने के लिए मेमोरी क्षेत्र चुनने की अनुमति दे सकते हैं। मुझे पता है कि ऐसी स्थिति हो सकती है जहां ढेर के सदस्य स्वीकार्य हो सकते हैं। यदि आप किसी स्थिति को जानते हैं तो आप इसका वर्णन कर सकते हैं?सी ++ शिष्टाचार पर सदस्य चर के बारे में शिष्टाचार

+0

"क्लाइंट को चुनने की अनुमति देना चाहते हैं" का क्या मतलब है? –

+0

कक्षा का उपयोग करने वाले व्यक्ति को परिभाषित करने दें कि उदाहरण स्मृति में क्या रखा गया है। आईई .: Classicreated client_obj = नया वर्गीकृत;/* या */classicreated client_obj; – bluehavana

+0

वह * सदस्य चर * के बारे में पूछ रहा है और जहां उन्हें स्मृति में रखा जाता है। यदि आप एक फू स्टैक-आवंटित करते हैं: Foo foo; फू के सूचक सदस्य उपयोगकर्ता की अपेक्षा किए बिना ढेर पर जा सकते हैं। आप उपयोगकर्ता को इसके चारों ओर जाने के लिए एक आवंटक निर्दिष्ट करने की अनुमति दे सकते हैं। – tgamblin

उत्तर

13

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

यदि आप अधिक लचीलापन चाहते हैं, तो अपने उपयोगकर्ता को Allocator निर्दिष्ट करने पर विचार करें। मैं समझाऊंगा।

कुछ कक्षाएं, उदा। std::vector, स्ट्रिंग, मानचित्र, आदि को उनके द्वारा प्रस्तुत डेटा संरचनाओं के लिए ढेर संग्रहण की आवश्यकता है। यह बुरा शिष्टाचार नहीं माना जाता है; जब आप एक स्वचालित रूप से vector आवंटित किया है, उपयोगकर्ता को पता है कि जब vector निर्माता कहा जाता हो जाता है एक बफर आवंटित किया जाता है की उम्मीद है:

void foo() { 
    // user of vector knows a buffer that can hold at least 10 ints 
    // gets allocated here. 
    std::vector<int> foo(10); 
} 

इसी तरह, std::string के लिए, तुम्हें पता है वहाँ एक आंतरिक, ढेर-आवंटित char*। चाहे प्रति string उदाहरण एक एसटीएल कार्यान्वयन पर है; अक्सर बार वे संदर्भ गिना जाता है।

हालांकि, लगभग सभी एसटीएल कक्षाओं के लिए, उपयोगकर्ता में चीजें हैं जहां चीजें रखी जाती हैं, इसमें वे एक आवंटक निर्दिष्ट कर सकते हैं। vector इस तरह तरह का परिभाषित किया गया है:

template <typename T, typename Alloc = DefaultAllocator<T> > 
class vector { 
    // etc. 
}; 

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

vector<int, MyCustomAllocator> foo(10); 

अब जब निर्माता आबंटित करता है, यह एक MyCustomAllocator डिफ़ॉल्ट के बजाय का उपयोग करेगा। यहां कुछ details on writing your own STL allocator हैं।

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

+0

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

+0

यह उत्तर और मैट डेविस के उत्तर दोनों को स्वीकार करने के लायक हैं। चूंकि स्वीकृति से कोई प्रतिनिधि प्राप्त नहीं हुआ है, इसलिए बस उन्हें दोनों महान उत्तर दें। आपका बहुत बहुत धन्यवाद। – bluehavana

0

हम्म, मैं वास्तव में आपके प्रश्न को समझ नहीं पा रहा हूं।

आप एक वर्ग है, तो:

class MyOtherClass; 
class MyClass 
{ 
    MyOtherClass* m_pStruct; 
}; 

फिर, MyClass की ग्राहक कैसे m_pStruct आवंटित किया जाएगा पर कोई वास्तविक विकल्प नहीं है।

लेकिन यह, कैसे वर्ग MyClass ही आवंटित किया जाएगा पर ग्राहक के निर्णय हो जाएगा या तो ढेर पर या ढेर पर:

MyClass* pMyClass = new MyClass; 

या

MyClass myClass; 
1

वर्ग कहाँ डालता है इसके सदस्यों की तुलना में कम महत्वपूर्ण है कि उनके प्रबंधन में कक्षा के भीतर निहित है; यानी ग्राहकों और उप-वर्गों को ऑब्जेक्ट के सदस्य चर के बारे में चिंता करने की ज़रूरत नहीं है।

ऐसा करने का सबसे आसान तरीका उन्हें चरम चर बनाने के लिए होगा। लेकिन कुछ मामलों में, जैसे कि आपकी कक्षा में एक लिखित सूची की तरह एक गतिशील डेटा संरचना है, यह समझ में नहीं आता है।

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

10

मुझे यह बिल्कुल बुरा अभ्यास नहीं लगता है। ऐसे सभी कारण हैं जिनसे आप स्पष्ट रूप से नए सदस्य के माध्यम से सदस्य चर आवंटित करना चाहते हैं। मेरे सिर के ऊपर से कुछ नीचे दिए गए हैं।

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

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

+0

अगर मैं दो उत्तरों स्वीकार कर सकता हूं, तो मैं इसे स्वीकार करूंगा और tgamblin की। सभी विभिन्न परिस्थितियों के लिए धन्यवाद, वे सभी समस्या के दायरे और समाधानों का एक व्यापक, व्यावहारिक दृष्टिकोण देने के लिए पर्याप्त हैं। – bluehavana

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