2011-06-09 14 views
9

यह होमवर्क है ... मैं जवाब मांग नहीं रहा हूं, मुझे बस एक बग है, मुझे यकीन नहीं है कि मुझे क्या करना है। धन्यवाद!सजावटी डिजाइन पैटर्न, फ़ंक्शन बग

प्रश्न में बग शायद काम के साथ ही लेना देना नहीं है, लेकिन यहाँ वैसे भी काम वर्णन है:

मैं एक काम पर काम कर रहा हूँ (सी ++ में) डेकोरेटर डिजाइन के उपयोग को पढ़ाने के लिए होती टॉपिंग के साथ एक पिज्जा के क्लासिक उदाहरण के माध्यम से पैटर्न। (मेरे प्रोफेसर ने इसे http://simplestcodings.com/2010/12/26/decorator-design-pattern-example-ni-c/ से सीधे उठाया है)। मैं एक छोटी सी समस्या में भाग रहा हूं कि मैं सोच रहा था कि कोई मेरी मदद कर सकता है या नहीं।

मेरे पास एक मुख्य मेनू (पिज़्ज़ेरिया) ऑब्जेक्ट है जो उपयोगकर्ता से इनपुट लेता है और पिज्जा पर वांछित क्रियाएं करता है। उपयोगकर्ता मूल पिज्जा से शुरू होते हैं और फिर जब तक वे पूरा नहीं कर लेते हैं तब तक टॉपिंग जोड़ सकते हैं। तो पहली बात यह है कि मेरा "नया पिज्जा" फ़ंक्शन नया पिज्जा Plain के रूप में घोषित करता है, जो अमूर्त वर्ग Pizza का उप-वर्ग है।

फिर वे अपनी टॉपिंग की पसंद में प्रवेश करते हैं। प्रत्येक बार, Pizza ऑब्जेक्ट के लिए पॉइंटर addToppings() फ़ंक्शन पर भेजा जाता है, नई सजावट जोड़ दी जाती है, और पॉइंटर वापस कर दिया जाता है। प्रत्येक सजावट मूल्य श्रेणी से प्राप्त होती है, जो pizzaToppings से प्राप्त होती है, जो Pizza से प्राप्त होती है।

यह मुख्य आदेश समारोह के प्रासंगिक हिस्सा है:

Pizza* Menu::newPizza() 
{ 
cout << "\nNew Pizza"; 

//accept the next choice 
int choose = 0; 

//create the new pizza 
Plain * currentPizza = new Plain(); 

//until they choose to end the order 
while (choose != 3) 
{ 
    //accept the choice 
    cin >> choose; 

    switch (choose) 
    { 
     //if they want to add a new topping 
    case 1: 
     { 
      //add topping to current pizza 
      //and this is where the problem is spotted by the compiler 
      addTopping(currentPizza); 
      break; 
     } 

मुद्दा यह है कि जब मैं समारोह addTopping() सूचक currentPizza भेजने का प्रयास करें, मैं "रन-टाइम जांच विफलता # 3 है - वैरिएबल 'currentPizza' का उपयोग शुरू किए बिना किया जा रहा है। "

क्या मैंने इसे लाइन 7 पर अभी शुरू नहीं किया था?

अगर मैं "जारी रखें" दबाता हूं, तो प्रोग्राम चल रहा है, और काम करता है, लेकिन जब भी मैं फ़ंक्शन को कॉल करता हूं तो मुझे वही त्रुटि मिलती है। क्या यह सिर्फ सिंटैक्स त्रुटि है, या क्या मेरे यहां कुछ वास्तविक समस्या है?

धन्यवाद !!

[संपादित करें:]

addTopping() फ़ंक्शन:

Pizza* Menu::addTopping(Pizza* thisPizza) 
{ 
cout << "\nAdd topping"; 

//declare choose int 
int choose = 0; 

//accept number of topping 
cin >> choose; 

//decide which one to add 
switch (choose) 
{ 

//mozzarella 
case 1: 
    { 
     thisPizza = new Mozzarella(thisPizza); 
     break; 
    } 
//mushrooms 
case 2: 
    { 
     thisPizza = new Mushrooms(thisPizza); 
     break; 
    } 

//another 13 possible toppings, won't bore you with the details ;) 

} 

cout << "\nEnd add topping\n"; 

return thisPizza; 
} 
+2

addTopping() कार्यान्वयन क्या है? यह प्रासंगिक – Simone

+0

हो सकता है क्या 'सादा' वर्ग में कुछ पीओडी सदस्य चर हैं जिन्हें प्रारंभ नहीं किया जा रहा है? –

+0

@ क्रिस, इसके कन्स्ट्रक्टर में कोई भी चीज़ नहीं है – BIU

उत्तर

6

आप currentPizza भी Pizza वर्ग के एक क्षेत्र के रूप में घोषित किया है और आप उपयोग कर रहे कहीं और है? यदि ऐसा है, तो currentPizza आप newPizza में अपडेट कर रहे हैं उस विधि के लिए विशिष्ट है, और आपको विधि के दायरे में एक नया currentPizza चर घोषित करने के बजाय currentPizza = new Plain(); करने की आवश्यकता है।

इसके अलावा, आपके addTopping विधि में, आप केवल तर्क thisPizza है, जो एक कॉपी सूचकcurrentPizza की अपडेट कर रहे हैं।

आप क्या करने की जरूरत:

currentPizza = addTopping(currentPizza); 
+0

मैंने नोटिस नहीं किया कि पोस्ट नहीं किया गया था। मुझे लगता है कि मैंने गलत संस्करण से कॉपी किया है, क्योंकि यह मेरे पास अब मेरे कोड में है। धन्यवाद :) – BIU

2

आप मूल्य से एक सूचक में पारित (जो आप क्या कर रहे है) यदि यह है कि सूचक मान ले और यह करने के लिए नए पिज्जा आवंटित करेगा। वह मान उतना ही नहीं है जितना ऊपर पंक्ति 7 में मिलता है। उदाहरण के लिए:

int bar = new int(3); 
void doSomething(int *foo){ foo = new int(5); } //memory leak here 
doSomething(bar); 

बार अभी भी 3. यह प्रभावी है कि आप क्या कर रहे हैं।

void doSomething(int **foo){ delete *foo; *foo = new int(5); } 

अद्यतन:

देखकर के रूप में आप एक नेस्टेड वर्ग संरचना, जिसमें वर्ग बाल एक वर्ग बेस के रिकार्ड को बरकरार रखे हुए चाहें

आप संदर्भ द्वारा सूचक में पास करना चाहते हैं एक बहुलक तरीके से ...

void doSomething(MyClass **foo){ *foo = new MyChildClass(*foo); } 

मुझे उम्मीद है कि बाल कक्षाओं में आपकी परिभाषा के हिस्से के रूप में आपने सुनिश्चित किया है कि आप संसाधनों की रिहाई को संभालने में कामयाब रहे हैं (यानी। पॉइंटर्स) सही ढंग से। मैं एक स्मार्ट सूचक को शामिल करने के लिए सुझाव देना चाहता हूं लेकिन यह असाइनमेंट के लिए आपको आवश्यकता से अधिक हो सकता है। वर्ष हटाए बिना जब से तुम ढेर पर नई वस्तु बनाने currentPizza = addTopping(currentPizza);

इसके अलावा, आप एक स्मृति रिसाव हो गया,,:

+0

मैं समझता हूं कि आप क्या कह रहे हैं, लेकिन कारण मैंने ऐसा नहीं किया क्योंकि मैं एक ही पिज्जा पर जाने के बाद टॉपिंग जोड़ने में सक्षम होना चाहता हूं। इसका मतलब यह नहीं होगा कि मैं हर बार खरोंच से शुरू करूँगा? – BIU

+0

@BIU मैं देखता हूं, मुझे जवाब देने के लिए उत्तर दें कि आप अपनी कक्षा संरचना के साथ क्या करने का प्रयास कर रहे हैं। – wheaties

1

एक गलती है कि Menu::newPizza() में यदि आप ऐसा नहीं करते हैं।

वैसे, खराब डिजाइन की तरह लगता है कि एड पिटिंग विधि से नया पिज्जा लौटाता है।

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