2011-06-09 49 views
9

這是作業...我不是要求答案,我只是有一個錯誤,我不知道該怎麼處理。謝謝!裝修設計模式,功能bug

有問題的錯誤可能有無關的分配本身,但這裏是委派描述反正:

我的工作分配(在C++)旨在教導使用裝飾設計通過帶澆頭的比薩餅的典型例子模式。 (我的教授也可能從http://simplestcodings.com/2010/12/26/decorator-design-pattern-example-ni-c/直接解除)。我遇到了一個小問題,我想知道是否有人可以幫助我。

我有一個主菜單(比薩店)對象,它接受用戶的輸入並在比薩上執行所需的操作。用戶從一個基本的披薩開始,然後可以添加配料直到完成。因此,我的「newPizza」函數所做的第一件事是將新比薩聲明爲Plain,它是抽象類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; 
     } 

的問題是,當我嘗試指針currentPizza發送到功能addTopping(),我得到 「運行時檢查失敗#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 2011-06-09 10:29:32

+0

'Plain'類是否有一些未被初始化的POD成員變量? – 2011-06-09 10:34:06

+0

@Chris,沒有它的一切都在它的構造函數 – BIU 2011-06-09 10:35:55

回答

6

你有currentPizza還宣佈作爲Pizza類的領域,你使用的是別的地方?如果是這樣,那麼currentPizza中更新的newPizza是特定於該方法的,並且您只需要執行currentPizza = new Plain();而不是在該方法的範圍內聲明新的currentPizza變量。

而且,在你addTopping方法,你只更新參數thisPizza,這是一個複製指針currentPizza

你需要做的:

currentPizza = addTopping(currentPizza); 
+0

我沒有注意到,沒有發佈。我想我從錯誤的版本複製,因爲這是我現在在我的代碼中的行。謝謝:) – BIU 2011-06-09 10:42:47

2

如果你在一個指針傳遞由值(這是你在做什麼),它會採取指針值和新的比薩餅分配給它。該值與上面第7行中的值不同。例如:

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

bar仍然是3.這就是你正在做的。

您想引用指針傳遞:

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

更新

看到,只要你願意嵌套類結構,其中兒童類保留了Base類的記錄以多態的方式...

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

我希望作爲您在子類中的定義的一部分,你已經確定你正在處理資源的釋放(即正確的指針)。我會建議您考慮合併一個智能指針,但這可能比您需要的任務更多。

+0

我明白你說的是什麼,但是我沒有這麼做的原因是因爲我打算在添加同樣的披薩之後添加頂部。這不是說我每次都會從頭開始嗎? – BIU 2011-06-09 10:51:41

+0

@BIU我看到了,讓我更新答案,以反映你試圖用你的班級結構做​​什麼。 – wheaties 2011-06-09 10:56:27

1

錯誤之一是,在Menu::newPizza()你不這樣做: currentPizza = addTopping(currentPizza);

而且你有內存泄漏,因爲你創建新的堆對象,而不刪除舊的。

順便說一句,聽起來像一個糟糕的設計從addTopping方法返回新的比薩餅。