2009-09-07 16 views
6

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

class Panda 
{ 
    int a; 
    int b; 
    int _bambooCount; 
    Bamboo* _bamboo; 

    Panda (int count, Bamboo* bamboo) 
    { 
    _bambooCount = count; 
    _bamboo = new Bamboo[count]; 

    // ... copy bamboo into the array ... 
    } 
} 

Bamboo ऑब्जेक्ट की श्रृंखला के आवंटन की भूमि के ऊपर कम करने के लिए, मैं इस वर्ग के रूप में निम्न प्रकार लागू कर सकता है

class Panda 
{ 
    int a; 
    int b; 

    Panda() 
    { 
     // ... other initializations here ... 
    } 

    static Panda *createPanda (int count, Bamboo* bamboo) 
    { 
    byte* p = new byte[sizeof(Panda) + 
     sizeof(Bamboo) * count]; 
    new (p) Panda(); 

    Bamboo* bamboo = (Bamboo*) 
     p + sizeof(Panda); 

    // ... copy bamboo objects into the memory 
     // behind the object... 

     return (Panda*)p; 
    } 
} 

आप दूसरे डिजाइन के साथ कोई समस्या पूर्वानुमान कर सकते हैं, वृद्धि हुई रखरखाव प्रयास के अलावा अन्य: विधि दोनों Panda वस्तु और उसके Bamboo सरणी धारण करने के लिए एक भी स्मृति ब्लॉक आवंटित करता? क्या यह एक स्वीकार्य डिजाइन पैटर्न है, या बस एक समयपूर्व अनुकूलन है जो बाद में मुझे काटने के लिए वापस आ सकता है?

+0

यह काट देगा। और यह कड़ी मेहनत करेगा। –

+1

आप सी ++ में कक्षा प्रकारों के लिए अधिकांश अर्थशास्त्र को तोड़ रहे हैं। परिवर्तनीय-लंबाई वाली वस्तुएं C++ में मौजूद नहीं हैं। – jalf

+2

यदि आप इस प्रकृति के आंखों के पानी के हैक में रूचि रखते हैं, तो आप सिम्बियन/सी ++ से टीबीयूफ़ 8 और टीबीएफ 16 वर्ग टेम्पलेट्स को भी देखना चाहेंगे। –

उत्तर

9

सी ++ आपको एक और विकल्प देता है। आपको std :: वेक्टर का उपयोग करने पर विचार करना चाहिए।

class Panda 
{ 
    int a; 
    int b; 
    std::vector<Bamboo> bamboo; 
    // if you do not want to store by value: 
    //std::vector< shared_ptr<Bamboo> > bamboo; 

    Panda (int count, Bamboo* bamb) : bamboo(bamb, bamb+count) {} 
} 

आप निरंतर स्मृति आप this article से समाधान इस्तेमाल कर सकते हैं में पांडा और बांस संग्रहीत करना चाहते हैं। मुख्य विचार operator new और operator delete अधिभारित करना है।

+0

आपको इस प्रकार के समाधानों के दुष्प्रभावों और उन समस्याओं के बारे में अवगत होना चाहिए जिनके साथ आपको निपटना होगा: उपयोगकर्ता कंटेनरों के अंदर वस्तुओं का उपयोग करने में सक्षम नहीं होंगे (विशेष रूप से std :: वेक्टर जो आकार के आधार पर स्मृति को पूर्ववत करता है टाइप किया गया प्रकार) यह चाल उस कोड के साथ समाप्त हो जाएगी जो केवल बनाए रखने के लिए मुश्किल नहीं है (प्रश्नकर्ता जानता है) लेकिन –

+0

का उपयोग करने के लिए अप्राकृतिक है 'std :: vector' का उपयोग करना सबसे स्वाभाविक है। अन्य सभी समाधानों का बहुत सीमित उपयोग होता है और सावधानी के साथ लागू किया जाना चाहिए। –

+0

यदि मुझे गलत नहीं लगता है तो जीसीसी के स्ट्रिंग कार्यान्वयन इस तरह की चालबाजी का उपयोग करता है। चाल यह है कि पांडा ऑब्जेक्ट में (समग्र) कार्यान्वयन वर्ग में एक सूचक हो सकता है। – UncleBens

1

आप नए ऑपरेटर के "नए" रूप का उपयोग करते हैं। यह रिश्तेदार पांडा पूरी तरह से सही है, लेकिन आप बांस प्रारंभकर्ता का उपयोग क्यों नहीं करते?

4

यदि कोई व्यक्ति पांडा को मूल्य से लेता है तो आप काट लेंगे उदा।

//compiler allocates 16-bytes on the stack for this local variable 
Panda panda = *createPanda(15, bamboo); 

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

3

मेरे अनुभव के आधार पर, समयपूर्व अनुकूलन हमेशा "समयपूर्व" होता है .. यही कहना है कि आपको अपना कोड प्रोफाइल करना चाहिए और यह निर्धारित करना चाहिए कि अनुकूलन की आवश्यकता है या आप बस अपने लिए अधिक काम कर रहे हैं आगे जाकर।

इसके अलावा, मुझे ऐसा लगता है कि अनुकूलन के लायक है या नहीं, यह बांस वर्ग के आकार और प्रति पांडा की बांस वस्तुओं की औसत संख्या पर निर्भर करता है।

3

यह सी
में पाया गया था लेकिन सी ++ में कोई वास्तविक आवश्यकता नहीं है।

असली सवाल यह है कि आप ऐसा क्यों करना चाहते हैं?

यह एक समयपूर्व अनुकूलन है, केवल एक std :: वेक्टर <> आंतरिक रूप से उपयोग करें और आपकी सभी समस्याएं गायब हो जाएंगी।

क्योंकि आप एक रॉ सूचक का उपयोग कर रहे आंतरिक रूप से उस वर्ग का मालिक आप के डिफ़ॉल्ट संस्करण ओवरराइड करने के लिए की आवश्यकता होगी:

  • डिफ़ॉल्ट निर्माता
  • नाशक
  • कॉपी निर्माता
  • असाइनमेंट ऑपरेटर
7

हम लोगों को कैसे समझते हैं कि प्रोग्रामिंग सादगी में और स्पष्टता - संक्षेप में: क्या गणितज्ञ 'लालित्य' कहते हैं - एक विवादास्पद लक्जरी नहीं है, लेकिन एक महत्वपूर्ण मामला जो सफलता और विफलता के बीच निर्णय लेता है?

- एडसगर W डिज्कस्ट्रा

+0

बस मत करो। कई चीजें गलत हो सकती हैं ... आप कॉपी कन्स्ट्रक्टर, असाइनमेंट, विनाशकों को कैसे लागू कर रहे हैं? आप उन उपयोगकर्ताओं से कैसे निपटने जा रहे हैं जो पांडा के सरणी चाहते हैं? –

+0

गणितज्ञों को प्रोग्रामिंग और असली दुनिया का कोई अंदाजा नहीं है। – Lothar

2

आप हताश है कि, तो आप शायद कुछ इस तरह कर सकते हैं कर रहे हैं:

template<std::size_t N> 
class Panda_with_bamboo : public Panda_without_bamboo 
{ 
    int a; 
    int b; 
    Bamboo bamboo[N]; 
} 

लेकिन मेरा मानना ​​है कि आप हताश नहीं हैं, लेकिन समय से पहले ही के अनुकूलन।

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